From 6599a4eb8b93ae14c01fe301c7e953047a71e2af Mon Sep 17 00:00:00 2001 From: Mathieu Desnoyers Date: Thu, 17 May 2018 14:20:47 -0400 Subject: [PATCH] ID tracker: implement vpid/uid/vuid/gid/vgid trackers Signed-off-by: Mathieu Desnoyers --- Makefile | 2 +- lttng-abi.c | 78 ++++++- lttng-abi.h | 23 ++ lttng-events.c | 245 ++++++++++++---------- lttng-events.h | 59 ++++-- lttng-tracker-pid.c => lttng-tracker-id.c | 125 +++++++---- probes/lttng-tracepoint-event-impl.h | 51 ++++- 7 files changed, 410 insertions(+), 173 deletions(-) rename lttng-tracker-pid.c => lttng-tracker-id.c (53%) diff --git a/Makefile b/Makefile index dfa5a588..8414837b 100644 --- a/Makefile +++ b/Makefile @@ -55,7 +55,7 @@ ifneq ($(KERNELRELEASE),) lttng-context-hostname.o wrapper/random.o \ probes/lttng.o wrapper/trace-clock.o \ wrapper/page_alloc.o \ - lttng-tracker-pid.o \ + lttng-tracker-id.o \ lttng-filter.o lttng-filter-interpreter.o \ lttng-filter-specialize.o \ lttng-filter-validator.o \ diff --git a/lttng-abi.c b/lttng-abi.c index c45c10f4..18b11507 100644 --- a/lttng-abi.c +++ b/lttng-abi.c @@ -463,6 +463,27 @@ fd_error: return ret; } +static +enum tracker_type get_tracker_type(struct lttng_kernel_tracker_args *tracker) +{ + switch (tracker->type) { + case LTTNG_KERNEL_TRACKER_PID: + return TRACKER_PID; + case LTTNG_KERNEL_TRACKER_VPID: + return TRACKER_VPID; + case LTTNG_KERNEL_TRACKER_UID: + return TRACKER_UID; + case LTTNG_KERNEL_TRACKER_VUID: + return TRACKER_VUID; + case LTTNG_KERNEL_TRACKER_GID: + return TRACKER_GID; + case LTTNG_KERNEL_TRACKER_VGID: + return TRACKER_VGID; + default: + return TRACKER_UNKNOWN; + } +} + /** * lttng_session_ioctl - lttng session fd ioctl * @@ -480,9 +501,13 @@ fd_error: * LTTNG_KERNEL_METADATA * Returns a LTTng metadata file descriptor * LTTNG_KERNEL_SESSION_TRACK_PID - * Add PID to session tracker + * Add PID to session PID tracker * LTTNG_KERNEL_SESSION_UNTRACK_PID - * Remove PID from session tracker + * Remove PID from session PID tracker + * LTTNG_KERNEL_SESSION_TRACK_ID + * Add ID to tracker + * LTTNG_KERNEL_SESSION_UNTRACK_ID + * Remove ID from tracker * * The returned channel will be deleted when its file descriptor is closed. */ @@ -563,11 +588,54 @@ long lttng_session_ioctl(struct file *file, unsigned int cmd, unsigned long arg) METADATA_CHANNEL); } case LTTNG_KERNEL_SESSION_TRACK_PID: - return lttng_session_track_pid(session, (int) arg); + return lttng_session_track_id(session, TRACKER_PID, (int) arg); case LTTNG_KERNEL_SESSION_UNTRACK_PID: - return lttng_session_untrack_pid(session, (int) arg); + return lttng_session_untrack_id(session, TRACKER_PID, (int) arg); + case LTTNG_KERNEL_SESSION_TRACK_ID: + { + struct lttng_kernel_tracker_args tracker; + enum tracker_type tracker_type; + + if (copy_from_user(&tracker, + (struct lttng_kernel_tracker_args __user *) arg, + sizeof(struct lttng_kernel_tracker_args))) + return -EFAULT; + tracker_type = get_tracker_type(&tracker); + if (tracker_type == TRACKER_UNKNOWN) + return -EINVAL; + return lttng_session_track_id(session, tracker_type, tracker.id); + } + case LTTNG_KERNEL_SESSION_UNTRACK_ID: + { + struct lttng_kernel_tracker_args tracker; + enum tracker_type tracker_type; + + if (copy_from_user(&tracker, + (struct lttng_kernel_tracker_args __user *) arg, + sizeof(struct lttng_kernel_tracker_args))) + return -EFAULT; + tracker_type = get_tracker_type(&tracker); + if (tracker_type == TRACKER_UNKNOWN) + return -EINVAL; + return lttng_session_untrack_id(session, tracker_type, + tracker.id); + } case LTTNG_KERNEL_SESSION_LIST_TRACKER_PIDS: - return lttng_session_list_tracker_pids(session); + return lttng_session_list_tracker_ids(session, TRACKER_PID); + case LTTNG_KERNEL_SESSION_LIST_TRACKER_IDS: + { + struct lttng_kernel_tracker_args tracker; + enum tracker_type tracker_type; + + if (copy_from_user(&tracker, + (struct lttng_kernel_tracker_args __user *) arg, + sizeof(struct lttng_kernel_tracker_args))) + return -EFAULT; + tracker_type = get_tracker_type(&tracker); + if (tracker_type == TRACKER_UNKNOWN) + return -EINVAL; + return lttng_session_list_tracker_ids(session, tracker_type); + } case LTTNG_KERNEL_SESSION_METADATA_REGEN: return lttng_session_metadata_regenerate(session); case LTTNG_KERNEL_SESSION_STATEDUMP: diff --git a/lttng-abi.h b/lttng-abi.h index 822b8839..dba0f20f 100644 --- a/lttng-abi.h +++ b/lttng-abi.h @@ -174,6 +174,22 @@ struct lttng_kernel_filter_bytecode { char data[0]; } __attribute__((packed)); +enum lttng_kernel_tracker_type { + LTTNG_KERNEL_TRACKER_UNKNOWN = -1, + + LTTNG_KERNEL_TRACKER_PID = 0, + LTTNG_KERNEL_TRACKER_VPID = 1, + LTTNG_KERNEL_TRACKER_UID = 2, + LTTNG_KERNEL_TRACKER_VUID = 3, + LTTNG_KERNEL_TRACKER_GID = 4, + LTTNG_KERNEL_TRACKER_VGID = 5, +}; + +struct lttng_kernel_tracker_args { + enum lttng_kernel_tracker_type type; + int32_t id; +}; + /* LTTng file descriptor ioctl */ #define LTTNG_KERNEL_SESSION _IO(0xF6, 0x45) #define LTTNG_KERNEL_TRACER_VERSION \ @@ -197,6 +213,7 @@ struct lttng_kernel_filter_bytecode { _IOR(0xF6, 0x58, int32_t) #define LTTNG_KERNEL_SESSION_UNTRACK_PID \ _IOR(0xF6, 0x59, int32_t) + /* * ioctl 0x58 and 0x59 are duplicated here. It works, since _IOR vs _IO * are generating two different ioctl numbers, but this was not done on @@ -206,6 +223,12 @@ struct lttng_kernel_filter_bytecode { #define LTTNG_KERNEL_SESSION_METADATA_REGEN _IO(0xF6, 0x59) /* 0x5A and 0x5B are reserved for a future ABI-breaking cleanup. */ #define LTTNG_KERNEL_SESSION_STATEDUMP _IO(0xF6, 0x5C) +#define LTTNG_KERNEL_SESSION_LIST_TRACKER_IDS \ + _IOR(0xF6, 0x5D, struct lttng_kernel_tracker_args) +#define LTTNG_KERNEL_SESSION_TRACK_ID \ + _IOR(0xF6, 0x5E, struct lttng_kernel_tracker_args) +#define LTTNG_KERNEL_SESSION_UNTRACK_ID \ + _IOR(0xF6, 0x5F, struct lttng_kernel_tracker_args) /* Channel FD ioctl */ #define LTTNG_KERNEL_STREAM _IO(0xF6, 0x62) diff --git a/lttng-events.c b/lttng-events.c index 5e9c72bf..ea2c5841 100644 --- a/lttng-events.c +++ b/lttng-events.c @@ -155,6 +155,18 @@ struct lttng_session *lttng_session_create(void) for (i = 0; i < LTTNG_EVENT_HT_SIZE; i++) INIT_HLIST_HEAD(&session->events_ht.table[i]); list_add(&session->list, &sessions); + session->pid_tracker.session = session; + session->pid_tracker.tracker_type = TRACKER_PID; + session->vpid_tracker.session = session; + session->vpid_tracker.tracker_type = TRACKER_VPID; + session->uid_tracker.session = session; + session->uid_tracker.tracker_type = TRACKER_UID; + session->vuid_tracker.session = session; + session->vuid_tracker.tracker_type = TRACKER_VUID; + session->gid_tracker.session = session; + session->gid_tracker.tracker_type = TRACKER_GID; + session->vgid_tracker.session = session; + session->vgid_tracker.tracker_type = TRACKER_VGID; mutex_unlock(&sessions_mutex); return session; @@ -205,8 +217,12 @@ void lttng_session_destroy(struct lttng_session *session) } list_for_each_entry(metadata_stream, &session->metadata_cache->metadata_stream, list) _lttng_metadata_channel_hangup(metadata_stream); - if (session->pid_tracker) - lttng_pid_tracker_destroy(session->pid_tracker); + lttng_id_tracker_destroy(&session->pid_tracker, false); + lttng_id_tracker_destroy(&session->vpid_tracker, false); + lttng_id_tracker_destroy(&session->uid_tracker, false); + lttng_id_tracker_destroy(&session->vuid_tracker, false); + lttng_id_tracker_destroy(&session->gid_tracker, false); + lttng_id_tracker_destroy(&session->vgid_tracker, false); kref_put(&session->metadata_cache->refcount, metadata_cache_destroy); list_del(&session->list); mutex_unlock(&sessions_mutex); @@ -904,91 +920,85 @@ void _lttng_event_destroy(struct lttng_event *event) kmem_cache_free(event_cache, event); } -int lttng_session_track_pid(struct lttng_session *session, int pid) +struct lttng_id_tracker *get_tracker(struct lttng_session *session, + enum tracker_type tracker_type) +{ + switch (tracker_type) { + case TRACKER_PID: + return &session->pid_tracker; + case TRACKER_VPID: + return &session->vpid_tracker; + case TRACKER_UID: + return &session->uid_tracker; + case TRACKER_VUID: + return &session->vuid_tracker; + case TRACKER_GID: + return &session->gid_tracker; + case TRACKER_VGID: + return &session->vgid_tracker; + default: + WARN_ON_ONCE(1); + return NULL; + } +} + +int lttng_session_track_id(struct lttng_session *session, + enum tracker_type tracker_type, int id) { + struct lttng_id_tracker *tracker; int ret; - if (pid < -1) + tracker = get_tracker(session, tracker_type); + if (!tracker) + return -EINVAL; + if (id < -1) return -EINVAL; mutex_lock(&sessions_mutex); - if (pid == -1) { - /* track all pids: destroy tracker. */ - if (session->pid_tracker) { - struct lttng_pid_tracker *lpf; - - lpf = session->pid_tracker; - rcu_assign_pointer(session->pid_tracker, NULL); - synchronize_trace(); - lttng_pid_tracker_destroy(lpf); - } + if (id == -1) { + /* track all ids: destroy tracker. */ + lttng_id_tracker_destroy(tracker, true); ret = 0; } else { - if (!session->pid_tracker) { - struct lttng_pid_tracker *lpf; - - lpf = lttng_pid_tracker_create(); - if (!lpf) { - ret = -ENOMEM; - goto unlock; - } - ret = lttng_pid_tracker_add(lpf, pid); - rcu_assign_pointer(session->pid_tracker, lpf); - } else { - ret = lttng_pid_tracker_add(session->pid_tracker, pid); - } + ret = lttng_id_tracker_add(tracker, id); } -unlock: mutex_unlock(&sessions_mutex); return ret; } -int lttng_session_untrack_pid(struct lttng_session *session, int pid) +int lttng_session_untrack_id(struct lttng_session *session, + enum tracker_type tracker_type, int id) { + struct lttng_id_tracker *tracker; int ret; - if (pid < -1) + tracker = get_tracker(session, tracker_type); + if (!tracker) + return -EINVAL; + if (id < -1) return -EINVAL; mutex_lock(&sessions_mutex); - if (pid == -1) { - /* untrack all pids: replace by empty tracker. */ - struct lttng_pid_tracker *old_lpf = session->pid_tracker; - struct lttng_pid_tracker *lpf; - - lpf = lttng_pid_tracker_create(); - if (!lpf) { - ret = -ENOMEM; - goto unlock; - } - rcu_assign_pointer(session->pid_tracker, lpf); - synchronize_trace(); - if (old_lpf) - lttng_pid_tracker_destroy(old_lpf); - ret = 0; + if (id == -1) { + /* untrack all ids: replace by empty tracker. */ + ret = lttng_id_tracker_empty_set(tracker); } else { - if (!session->pid_tracker) { - ret = -ENOENT; - goto unlock; - } - ret = lttng_pid_tracker_del(session->pid_tracker, pid); + ret = lttng_id_tracker_del(tracker, id); } -unlock: mutex_unlock(&sessions_mutex); return ret; } static -void *pid_list_start(struct seq_file *m, loff_t *pos) +void *id_list_start(struct seq_file *m, loff_t *pos) { - struct lttng_session *session = m->private; - struct lttng_pid_tracker *lpf; - struct lttng_pid_hash_node *e; + struct lttng_id_tracker *id_tracker = m->private; + struct lttng_id_tracker_rcu *id_tracker_p = id_tracker->p; + struct lttng_id_hash_node *e; int iter = 0, i; mutex_lock(&sessions_mutex); - lpf = session->pid_tracker; - if (lpf) { - for (i = 0; i < LTTNG_PID_TABLE_SIZE; i++) { - struct hlist_head *head = &lpf->pid_hash[i]; + if (id_tracker_p) { + for (i = 0; i < LTTNG_ID_TABLE_SIZE; i++) { + struct hlist_head *head = &id_tracker_p->id_hash[i]; lttng_hlist_for_each_entry(e, head, hlist) { if (iter++ >= *pos) @@ -996,9 +1006,9 @@ void *pid_list_start(struct seq_file *m, loff_t *pos) } } } else { - /* PID tracker disabled. */ + /* ID tracker disabled. */ if (iter >= *pos && iter == 0) { - return session; /* empty tracker */ + return id_tracker_p; /* empty tracker */ } iter++; } @@ -1008,18 +1018,17 @@ void *pid_list_start(struct seq_file *m, loff_t *pos) /* Called with sessions_mutex held. */ static -void *pid_list_next(struct seq_file *m, void *p, loff_t *ppos) +void *id_list_next(struct seq_file *m, void *p, loff_t *ppos) { - struct lttng_session *session = m->private; - struct lttng_pid_tracker *lpf; - struct lttng_pid_hash_node *e; + struct lttng_id_tracker *id_tracker = m->private; + struct lttng_id_tracker_rcu *id_tracker_p = id_tracker->p; + struct lttng_id_hash_node *e; int iter = 0, i; (*ppos)++; - lpf = session->pid_tracker; - if (lpf) { - for (i = 0; i < LTTNG_PID_TABLE_SIZE; i++) { - struct hlist_head *head = &lpf->pid_hash[i]; + if (id_tracker_p) { + for (i = 0; i < LTTNG_ID_TABLE_SIZE; i++) { + struct hlist_head *head = &id_tracker_p->id_hash[i]; lttng_hlist_for_each_entry(e, head, hlist) { if (iter++ >= *ppos) @@ -1027,9 +1036,9 @@ void *pid_list_next(struct seq_file *m, void *p, loff_t *ppos) } } } else { - /* PID tracker disabled. */ + /* ID tracker disabled. */ if (iter >= *ppos && iter == 0) - return session; /* empty tracker */ + return p; /* empty tracker */ iter++; } @@ -1038,67 +1047,91 @@ void *pid_list_next(struct seq_file *m, void *p, loff_t *ppos) } static -void pid_list_stop(struct seq_file *m, void *p) +void id_list_stop(struct seq_file *m, void *p) { mutex_unlock(&sessions_mutex); } static -int pid_list_show(struct seq_file *m, void *p) +int id_list_show(struct seq_file *m, void *p) { - int pid; + struct lttng_id_tracker *id_tracker = m->private; + struct lttng_id_tracker_rcu *id_tracker_p = id_tracker->p; + int id; - if (p == m->private) { + if (p == id_tracker_p) { /* Tracker disabled. */ - pid = -1; + id = -1; } else { - const struct lttng_pid_hash_node *e = p; + const struct lttng_id_hash_node *e = p; - pid = lttng_pid_tracker_get_node_pid(e); + id = lttng_id_tracker_get_node_id(e); + } + switch (id_tracker->tracker_type) { + case TRACKER_PID: + seq_printf(m, "process { pid = %d; };\n", id); + break; + case TRACKER_VPID: + seq_printf(m, "process { vpid = %d; };\n", id); + break; + case TRACKER_UID: + seq_printf(m, "user { uid = %d; };\n", id); + break; + case TRACKER_VUID: + seq_printf(m, "user { vuid = %d; };\n", id); + break; + case TRACKER_GID: + seq_printf(m, "group { gid = %d; };\n", id); + break; + case TRACKER_VGID: + seq_printf(m, "group { vgid = %d; };\n", id); + break; + default: + seq_printf(m, "UNKNOWN { field = %d };\n", id); } - seq_printf(m, "process { pid = %d; };\n", pid); return 0; } static -const struct seq_operations lttng_tracker_pids_list_seq_ops = { - .start = pid_list_start, - .next = pid_list_next, - .stop = pid_list_stop, - .show = pid_list_show, +const struct seq_operations lttng_tracker_ids_list_seq_ops = { + .start = id_list_start, + .next = id_list_next, + .stop = id_list_stop, + .show = id_list_show, }; static -int lttng_tracker_pids_list_open(struct inode *inode, struct file *file) +int lttng_tracker_ids_list_open(struct inode *inode, struct file *file) { - return seq_open(file, <tng_tracker_pids_list_seq_ops); + return seq_open(file, <tng_tracker_ids_list_seq_ops); } static -int lttng_tracker_pids_list_release(struct inode *inode, struct file *file) +int lttng_tracker_ids_list_release(struct inode *inode, struct file *file) { struct seq_file *m = file->private_data; - struct lttng_session *session = m->private; + struct lttng_id_tracker *id_tracker = m->private; int ret; - WARN_ON_ONCE(!session); + WARN_ON_ONCE(!id_tracker); ret = seq_release(inode, file); - if (!ret && session) - fput(session->file); + if (!ret) + fput(id_tracker->session->file); return ret; } -const struct file_operations lttng_tracker_pids_list_fops = { +const struct file_operations lttng_tracker_ids_list_fops = { .owner = THIS_MODULE, - .open = lttng_tracker_pids_list_open, + .open = lttng_tracker_ids_list_open, .read = seq_read, .llseek = seq_lseek, - .release = lttng_tracker_pids_list_release, + .release = lttng_tracker_ids_list_release, }; -int lttng_session_list_tracker_pids(struct lttng_session *session) +int lttng_session_list_tracker_ids(struct lttng_session *session, + enum tracker_type tracker_type) { - struct file *tracker_pids_list_file; + struct file *tracker_ids_list_file; struct seq_file *m; int file_fd, ret; @@ -1108,30 +1141,32 @@ int lttng_session_list_tracker_pids(struct lttng_session *session) goto fd_error; } - tracker_pids_list_file = anon_inode_getfile("[lttng_tracker_pids_list]", - <tng_tracker_pids_list_fops, + tracker_ids_list_file = anon_inode_getfile("[lttng_tracker_ids_list]", + <tng_tracker_ids_list_fops, NULL, O_RDWR); - if (IS_ERR(tracker_pids_list_file)) { - ret = PTR_ERR(tracker_pids_list_file); + if (IS_ERR(tracker_ids_list_file)) { + ret = PTR_ERR(tracker_ids_list_file); goto file_error; } if (atomic_long_add_unless(&session->file->f_count, 1, INT_MAX) == INT_MAX) { goto refcount_error; } - ret = lttng_tracker_pids_list_fops.open(NULL, tracker_pids_list_file); + ret = lttng_tracker_ids_list_fops.open(NULL, tracker_ids_list_file); if (ret < 0) goto open_error; - m = tracker_pids_list_file->private_data; - m->private = session; - fd_install(file_fd, tracker_pids_list_file); + m = tracker_ids_list_file->private_data; + + m->private = get_tracker(session, tracker_type); + BUG_ON(!m->private); + fd_install(file_fd, tracker_ids_list_file); return file_fd; open_error: atomic_long_dec(&session->file->f_count); refcount_error: - fput(tracker_pids_list_file); + fput(tracker_ids_list_file); file_error: put_unused_fd(file_fd); fd_error: diff --git a/lttng-events.h b/lttng-events.h index 5a96bf31..c3f23a5e 100644 --- a/lttng-events.h +++ b/lttng-events.h @@ -478,19 +478,36 @@ struct lttng_dynamic_len_stack { DECLARE_PER_CPU(struct lttng_dynamic_len_stack, lttng_dynamic_len_stack); /* - * struct lttng_pid_tracker declared in header due to deferencing of *v + * struct lttng_id_tracker declared in header due to deferencing of *v * in RCU_INITIALIZER(v). */ -#define LTTNG_PID_HASH_BITS 6 -#define LTTNG_PID_TABLE_SIZE (1 << LTTNG_PID_HASH_BITS) +#define LTTNG_ID_HASH_BITS 6 +#define LTTNG_ID_TABLE_SIZE (1 << LTTNG_ID_HASH_BITS) -struct lttng_pid_tracker { - struct hlist_head pid_hash[LTTNG_PID_TABLE_SIZE]; +enum tracker_type { + TRACKER_PID, + TRACKER_VPID, + TRACKER_UID, + TRACKER_VUID, + TRACKER_GID, + TRACKER_VGID, + + TRACKER_UNKNOWN, +}; + +struct lttng_id_tracker_rcu { + struct hlist_head id_hash[LTTNG_ID_TABLE_SIZE]; +}; + +struct lttng_id_tracker { + struct lttng_session *session; + enum tracker_type tracker_type; + struct lttng_id_tracker_rcu *p; /* RCU dereferenced. */ }; -struct lttng_pid_hash_node { +struct lttng_id_hash_node { struct hlist_node hlist; - int pid; + int id; }; struct lttng_session { @@ -503,7 +520,12 @@ struct lttng_session { unsigned int free_chan_id; /* Next chan ID to allocate */ uuid_le uuid; /* Trace session unique ID */ struct lttng_metadata_cache *metadata_cache; - struct lttng_pid_tracker *pid_tracker; + struct lttng_id_tracker pid_tracker; + struct lttng_id_tracker vpid_tracker; + struct lttng_id_tracker uid_tracker; + struct lttng_id_tracker vuid_tracker; + struct lttng_id_tracker gid_tracker; + struct lttng_id_tracker vgid_tracker; unsigned int metadata_dumped:1, tstate:1; /* Transient enable state */ /* List of enablers */ @@ -598,17 +620,20 @@ void lttng_probes_exit(void); int lttng_metadata_output_channel(struct lttng_metadata_stream *stream, struct channel *chan); -int lttng_pid_tracker_get_node_pid(const struct lttng_pid_hash_node *node); -struct lttng_pid_tracker *lttng_pid_tracker_create(void); -void lttng_pid_tracker_destroy(struct lttng_pid_tracker *lpf); -bool lttng_pid_tracker_lookup(struct lttng_pid_tracker *lpf, int pid); -int lttng_pid_tracker_add(struct lttng_pid_tracker *lpf, int pid); -int lttng_pid_tracker_del(struct lttng_pid_tracker *lpf, int pid); +int lttng_id_tracker_get_node_id(const struct lttng_id_hash_node *node); +int lttng_id_tracker_empty_set(struct lttng_id_tracker *lf); +void lttng_id_tracker_destroy(struct lttng_id_tracker *lf, bool rcu); +bool lttng_id_tracker_lookup(struct lttng_id_tracker_rcu *p, int id); +int lttng_id_tracker_add(struct lttng_id_tracker *lf, int id); +int lttng_id_tracker_del(struct lttng_id_tracker *lf, int id); -int lttng_session_track_pid(struct lttng_session *session, int pid); -int lttng_session_untrack_pid(struct lttng_session *session, int pid); +int lttng_session_track_id(struct lttng_session *session, + enum tracker_type tracker_type, int id); +int lttng_session_untrack_id(struct lttng_session *session, + enum tracker_type tracker_type, int id); -int lttng_session_list_tracker_pids(struct lttng_session *session); +int lttng_session_list_tracker_ids(struct lttng_session *session, + enum tracker_type tracker_type); void lttng_clock_ref(void); void lttng_clock_unref(void); diff --git a/lttng-tracker-pid.c b/lttng-tracker-id.c similarity index 53% rename from lttng-tracker-pid.c rename to lttng-tracker-id.c index 02b15c42..9194c2d3 100644 --- a/lttng-tracker-pid.c +++ b/lttng-tracker-id.c @@ -43,62 +43,83 @@ * sessions_mutex across calls to create, destroy, add, and del * functions of this API. */ -int lttng_pid_tracker_get_node_pid(const struct lttng_pid_hash_node *node) +int lttng_id_tracker_get_node_id(const struct lttng_id_hash_node *node) { - return node->pid; + return node->id; } /* * Lookup performed from RCU read-side critical section (RCU sched), * protected by preemption off at the tracepoint call site. - * Return 1 if found, 0 if not found. + * Return true if found, false if not found. */ -bool lttng_pid_tracker_lookup(struct lttng_pid_tracker *lpf, int pid) +bool lttng_id_tracker_lookup(struct lttng_id_tracker_rcu *p, int id) { struct hlist_head *head; - struct lttng_pid_hash_node *e; - uint32_t hash = hash_32(pid, 32); + struct lttng_id_hash_node *e; + uint32_t hash = hash_32(id, 32); - head = &lpf->pid_hash[hash & (LTTNG_PID_TABLE_SIZE - 1)]; + head = &p->id_hash[hash & (LTTNG_ID_TABLE_SIZE - 1)]; lttng_hlist_for_each_entry_rcu(e, head, hlist) { - if (pid == e->pid) - return 1; /* Found */ + if (id == e->id) + return true; /* Found */ } - return 0; + return false; +} +EXPORT_SYMBOL_GPL(lttng_id_tracker_lookup); + +static struct lttng_id_tracker_rcu *lttng_id_tracker_rcu_create(void) +{ + struct lttng_id_tracker_rcu *tracker; + + tracker = kzalloc(sizeof(struct lttng_id_tracker_rcu), GFP_KERNEL); + if (!tracker) + return NULL; + return tracker; } -EXPORT_SYMBOL_GPL(lttng_pid_tracker_lookup); /* * Tracker add and del operations support concurrent RCU lookups. */ -int lttng_pid_tracker_add(struct lttng_pid_tracker *lpf, int pid) +int lttng_id_tracker_add(struct lttng_id_tracker *lf, int id) { struct hlist_head *head; - struct lttng_pid_hash_node *e; - uint32_t hash = hash_32(pid, 32); + struct lttng_id_hash_node *e; + struct lttng_id_tracker_rcu *p = lf->p; + uint32_t hash = hash_32(id, 32); + bool allocated = false; - head = &lpf->pid_hash[hash & (LTTNG_PID_TABLE_SIZE - 1)]; + if (!p) { + p = lttng_id_tracker_rcu_create(); + if (!p) + return -ENOMEM; + allocated = true; + } + head = &p->id_hash[hash & (LTTNG_ID_TABLE_SIZE - 1)]; lttng_hlist_for_each_entry(e, head, hlist) { - if (pid == e->pid) + if (id == e->id) return -EEXIST; } - e = kmalloc(sizeof(struct lttng_pid_hash_node), GFP_KERNEL); + e = kmalloc(sizeof(struct lttng_id_hash_node), GFP_KERNEL); if (!e) return -ENOMEM; - e->pid = pid; + e->id = id; hlist_add_head_rcu(&e->hlist, head); + if (allocated) { + rcu_assign_pointer(lf->p, p); + } return 0; } static -void pid_tracker_del_node_rcu(struct lttng_pid_hash_node *e) +void id_tracker_del_node_rcu(struct lttng_id_hash_node *e) { hlist_del_rcu(&e->hlist); /* * We choose to use a heavyweight synchronize on removal here, - * since removal of a PID from the tracker mask is a rare + * since removal of an ID from the tracker mask is a rare * operation, and we don't want to use more cache lines than - * what we really need when doing the PID lookups, so we don't + * what we really need when doing the ID lookups, so we don't * want to afford adding a rcu_head field to those pid hash * node. */ @@ -111,48 +132,74 @@ void pid_tracker_del_node_rcu(struct lttng_pid_hash_node *e) * concurrent RCU lookups. */ static -void pid_tracker_del_node(struct lttng_pid_hash_node *e) +void id_tracker_del_node(struct lttng_id_hash_node *e) { hlist_del(&e->hlist); kfree(e); } -int lttng_pid_tracker_del(struct lttng_pid_tracker *lpf, int pid) +int lttng_id_tracker_del(struct lttng_id_tracker *lf, int id) { struct hlist_head *head; - struct lttng_pid_hash_node *e; - uint32_t hash = hash_32(pid, 32); + struct lttng_id_hash_node *e; + struct lttng_id_tracker_rcu *p = lf->p; + uint32_t hash = hash_32(id, 32); - head = &lpf->pid_hash[hash & (LTTNG_PID_TABLE_SIZE - 1)]; + if (!p) + return -ENOENT; + head = &p->id_hash[hash & (LTTNG_ID_TABLE_SIZE - 1)]; /* * No need of _safe iteration, because we stop traversal as soon * as we remove the entry. */ lttng_hlist_for_each_entry(e, head, hlist) { - if (pid == e->pid) { - pid_tracker_del_node_rcu(e); + if (id == e->id) { + id_tracker_del_node_rcu(e); return 0; } } return -ENOENT; /* Not found */ } -struct lttng_pid_tracker *lttng_pid_tracker_create(void) -{ - return kzalloc(sizeof(struct lttng_pid_tracker), GFP_KERNEL); -} - -void lttng_pid_tracker_destroy(struct lttng_pid_tracker *lpf) +static void lttng_id_tracker_rcu_destroy(struct lttng_id_tracker_rcu *p) { int i; - for (i = 0; i < LTTNG_PID_TABLE_SIZE; i++) { - struct hlist_head *head = &lpf->pid_hash[i]; - struct lttng_pid_hash_node *e; + if (!p) + return; + for (i = 0; i < LTTNG_ID_TABLE_SIZE; i++) { + struct hlist_head *head = &p->id_hash[i]; + struct lttng_id_hash_node *e; struct hlist_node *tmp; lttng_hlist_for_each_entry_safe(e, tmp, head, hlist) - pid_tracker_del_node(e); + id_tracker_del_node(e); } - kfree(lpf); + kfree(p); +} + +int lttng_id_tracker_empty_set(struct lttng_id_tracker *lf) +{ + struct lttng_id_tracker_rcu *p, *oldp; + + p = lttng_id_tracker_rcu_create(); + if (!p) + return -ENOMEM; + oldp = lf->p; + rcu_assign_pointer(lf->p, p); + synchronize_trace(); + lttng_id_tracker_rcu_destroy(oldp); + return 0; +} + +void lttng_id_tracker_destroy(struct lttng_id_tracker *lf, bool rcu) +{ + struct lttng_id_tracker_rcu *p = lf->p; + + if (!lf->p) + return; + rcu_assign_pointer(lf->p, NULL); + if (rcu) + synchronize_trace(); + lttng_id_tracker_rcu_destroy(p); } diff --git a/probes/lttng-tracepoint-event-impl.h b/probes/lttng-tracepoint-event-impl.h index 0842dcc0..b615eeab 100644 --- a/probes/lttng-tracepoint-event-impl.h +++ b/probes/lttng-tracepoint-event-impl.h @@ -24,6 +24,7 @@ #include #include #include +#include #include #include @@ -1140,7 +1141,7 @@ static void __event_probe__##_name(void *__data, _proto) \ struct probe_local_vars __tp_locvar; \ struct probe_local_vars *tp_locvar __attribute__((unused)) = \ &__tp_locvar; \ - struct lttng_pid_tracker *__lpf; \ + struct lttng_id_tracker_rcu *__lf; \ \ if (!_TP_SESSION_CHECK(session, __session)) \ return; \ @@ -1150,8 +1151,27 @@ static void __event_probe__##_name(void *__data, _proto) \ return; \ if (unlikely(!READ_ONCE(__event->enabled))) \ return; \ - __lpf = lttng_rcu_dereference(__session->pid_tracker); \ - if (__lpf && likely(!lttng_pid_tracker_lookup(__lpf, current->tgid))) \ + __lf = lttng_rcu_dereference(__session->pid_tracker.p); \ + if (__lf && likely(!lttng_id_tracker_lookup(__lf, current->tgid))) \ + return; \ + __lf = lttng_rcu_dereference(__session->vpid_tracker.p); \ + if (__lf && likely(!lttng_id_tracker_lookup(__lf, task_tgid_vnr(current)))) \ + return; \ + __lf = lttng_rcu_dereference(__session->uid_tracker.p); \ + if (__lf && likely(!lttng_id_tracker_lookup(__lf, \ + from_kuid(&init_user_ns, current_uid())))) \ + return; \ + __lf = lttng_rcu_dereference(__session->vuid_tracker.p); \ + if (__lf && likely(!lttng_id_tracker_lookup(__lf, \ + from_kuid(current_user_ns(), current_uid())))) \ + return; \ + __lf = lttng_rcu_dereference(__session->gid_tracker.p); \ + if (__lf && likely(!lttng_id_tracker_lookup(__lf, \ + from_kgid(&init_user_ns, current_gid())))) \ + return; \ + __lf = lttng_rcu_dereference(__session->vgid_tracker.p); \ + if (__lf && likely(!lttng_id_tracker_lookup(__lf, \ + from_kgid(current_user_ns(), current_gid())))) \ return; \ __orig_dynamic_len_offset = this_cpu_ptr(<tng_dynamic_len_stack)->offset; \ __dynamic_len_idx = __orig_dynamic_len_offset; \ @@ -1214,7 +1234,7 @@ static void __event_probe__##_name(void *__data) \ struct probe_local_vars __tp_locvar; \ struct probe_local_vars *tp_locvar __attribute__((unused)) = \ &__tp_locvar; \ - struct lttng_pid_tracker *__lpf; \ + struct lttng_id_tracker_rcu *__lf; \ \ if (!_TP_SESSION_CHECK(session, __session)) \ return; \ @@ -1224,8 +1244,27 @@ static void __event_probe__##_name(void *__data) \ return; \ if (unlikely(!READ_ONCE(__event->enabled))) \ return; \ - __lpf = lttng_rcu_dereference(__session->pid_tracker); \ - if (__lpf && likely(!lttng_pid_tracker_lookup(__lpf, current->pid))) \ + __lf = lttng_rcu_dereference(__session->pid_tracker.p); \ + if (__lf && likely(!lttng_id_tracker_lookup(__lf, current->tgid))) \ + return; \ + __lf = lttng_rcu_dereference(__session->vpid_tracker.p); \ + if (__lf && likely(!lttng_id_tracker_lookup(__lf, task_tgid_vnr(current)))) \ + return; \ + __lf = lttng_rcu_dereference(__session->uid_tracker.p); \ + if (__lf && likely(!lttng_id_tracker_lookup(__lf, \ + from_kuid(&init_user_ns, current_uid())))) \ + return; \ + __lf = lttng_rcu_dereference(__session->vuid_tracker.p); \ + if (__lf && likely(!lttng_id_tracker_lookup(__lf, \ + from_kuid(current_user_ns(), current_uid())))) \ + return; \ + __lf = lttng_rcu_dereference(__session->gid_tracker.p); \ + if (__lf && likely(!lttng_id_tracker_lookup(__lf, \ + from_kgid(&init_user_ns, current_gid())))) \ + return; \ + __lf = lttng_rcu_dereference(__session->vgid_tracker.p); \ + if (__lf && likely(!lttng_id_tracker_lookup(__lf, \ + from_kgid(current_user_ns(), current_gid())))) \ return; \ __orig_dynamic_len_offset = this_cpu_ptr(<tng_dynamic_len_stack)->offset; \ __dynamic_len_idx = __orig_dynamic_len_offset; \ -- 2.34.1