ID tracker: implement vpid/uid/vuid/gid/vgid trackers
authorMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Tue, 17 Dec 2019 15:17:01 +0000 (10:17 -0500)
committerMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Tue, 17 Dec 2019 15:17:56 +0000 (10:17 -0500)
Co-developed-by: Jonathan Rajotte <jonathan.rajotte-julien@efficios.com>
Signed-off-by: Jonathan Rajotte <jonathan.rajotte-julien@efficios.com>
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Makefile
lttng-abi.c
lttng-abi.h
lttng-events.c
lttng-events.h
lttng-tracker-id.c [new file with mode: 0644]
lttng-tracker-pid.c [deleted file]
probes/lttng-tracepoint-event-impl.h

index 709b5dc022cc5e4876d10c6e722b7d19a6d47074..4a6ddbc5f870d56fad5ea8c7ff16b173fca35606 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -66,7 +66,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 \
index 5c6f384d8fc62c6b40a229a30d9036a0be9f3f9e..4df3d673b18c0d84e4d80047fdf096ed52a81350 100644 (file)
@@ -525,6 +525,27 @@ int lttng_abi_session_set_creation_time(struct lttng_session *session,
        return 0;
 }
 
+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
  *
@@ -542,9 +563,13 @@ int lttng_abi_session_set_creation_time(struct lttng_session *session,
  *     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.
  */
@@ -617,11 +642,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:
index 9d345f4a7c841fe683e5872ee2eb6eeb958a176d..5c5d8256be55b654be4fb8fe235089ffa4b278c7 100644 (file)
@@ -208,6 +208,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 */
 /* lttng-abi-old.h reserve 0x40, 0x41, 0x42, 0x43, and 0x44. */
 #define LTTNG_KERNEL_SESSION                   _IO(0xF6, 0x45)
@@ -233,6 +249,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
@@ -270,6 +287,14 @@ struct lttng_kernel_filter_bytecode {
 #define LTTNG_KERNEL_FILTER                    _IO(0xF6, 0x90)
 #define LTTNG_KERNEL_ADD_CALLSITE              _IO(0xF6, 0x91)
 
+/* Session FD ioctl (continued) */
+#define LTTNG_KERNEL_SESSION_LIST_TRACKER_IDS  \
+       _IOR(0xF6, 0xA0, struct lttng_kernel_tracker_args)
+#define LTTNG_KERNEL_SESSION_TRACK_ID          \
+       _IOR(0xF6, 0xA1, struct lttng_kernel_tracker_args)
+#define LTTNG_KERNEL_SESSION_UNTRACK_ID                \
+       _IOR(0xF6, 0xA2, struct lttng_kernel_tracker_args)
+
 /*
  * LTTng-specific ioctls for the lib ringbuffer.
  *
index 4588153bf2d76a3f1fe8190a9119b69285ca0b6c..1ccbffd67fe60a961de18cf6b4c58d7334d1c155 100644 (file)
@@ -149,6 +149,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;
 
@@ -199,8 +211,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);
@@ -930,91 +946,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)
@@ -1022,9 +1032,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++;
        }
@@ -1034,18 +1044,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)
@@ -1053,9 +1062,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++;
        }
 
@@ -1064,67 +1073,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, &lttng_tracker_pids_list_seq_ops);
+       return seq_open(file, &lttng_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;
 
@@ -1134,30 +1167,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]",
-                                         &lttng_tracker_pids_list_fops,
+       tracker_ids_list_file = anon_inode_getfile("[lttng_tracker_ids_list]",
+                                         &lttng_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, LONG_MAX)) {
                ret = -EOVERFLOW;
                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:
index cdb520e8dd91fe07ae3f121a02f5fefe8ba52704..78b427a317d18972e9cea252b62154fc11b66b4d 100644 (file)
@@ -489,19 +489,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 {
@@ -514,7 +531,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 */
@@ -611,17 +633,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-id.c b/lttng-tracker-id.c
new file mode 100644 (file)
index 0000000..9a4b98b
--- /dev/null
@@ -0,0 +1,192 @@
+/* SPDX-License-Identifier: (GPL-2.0 or LGPL-2.1)
+ *
+ * lttng-tracker-pid.c
+ *
+ * LTTng Process ID tracking.
+ *
+ * Copyright (C) 2014 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+ */
+
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/err.h>
+#include <linux/seq_file.h>
+#include <linux/stringify.h>
+#include <linux/hash.h>
+#include <linux/rcupdate.h>
+
+#include <wrapper/tracepoint.h>
+#include <wrapper/rcu.h>
+#include <wrapper/list.h>
+#include <lttng-events.h>
+
+/*
+ * Hash table is allocated and freed when there are no possible
+ * concurrent lookups (ensured by the alloc/free caller). However,
+ * there can be concurrent RCU lookups vs add/del operations.
+ *
+ * Concurrent updates of the PID hash table are forbidden: the caller
+ * must ensure mutual exclusion. This is currently done by holding the
+ * sessions_mutex across calls to create, destroy, add, and del
+ * functions of this API.
+ */
+int lttng_id_tracker_get_node_id(const struct lttng_id_hash_node *node)
+{
+       return node->id;
+}
+
+/*
+ * Lookup performed from RCU read-side critical section (RCU sched),
+ * protected by preemption off at the tracepoint call site.
+ * Return true if found, false if not found.
+ */
+bool lttng_id_tracker_lookup(struct lttng_id_tracker_rcu *p, int id)
+{
+       struct hlist_head *head;
+       struct lttng_id_hash_node *e;
+       uint32_t hash = hash_32(id, 32);
+
+       head = &p->id_hash[hash & (LTTNG_ID_TABLE_SIZE - 1)];
+       lttng_hlist_for_each_entry_rcu(e, head, hlist) {
+               if (id == e->id)
+                       return true;    /* Found */
+       }
+       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;
+}
+
+/*
+ * Tracker add and del operations support concurrent RCU lookups.
+ */
+int lttng_id_tracker_add(struct lttng_id_tracker *lf, int id)
+{
+       struct hlist_head *head;
+       struct lttng_id_hash_node *e;
+       struct lttng_id_tracker_rcu *p = lf->p;
+       uint32_t hash = hash_32(id, 32);
+       bool allocated = false;
+
+       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 (id == e->id)
+                       return -EEXIST;
+       }
+       e = kmalloc(sizeof(struct lttng_id_hash_node), GFP_KERNEL);
+       if (!e)
+               return -ENOMEM;
+       e->id = id;
+       hlist_add_head_rcu(&e->hlist, head);
+       if (allocated) {
+               rcu_assign_pointer(lf->p, p);
+       }
+       return 0;
+}
+
+static
+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 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 ID lookups, so we don't
+        * want to afford adding a rcu_head field to those pid hash
+        * node.
+        */
+       synchronize_trace();
+       kfree(e);
+}
+
+/*
+ * This removal is only used on destroy, so it does not need to support
+ * concurrent RCU lookups.
+ */
+static
+void id_tracker_del_node(struct lttng_id_hash_node *e)
+{
+       hlist_del(&e->hlist);
+       kfree(e);
+}
+
+int lttng_id_tracker_del(struct lttng_id_tracker *lf, int id)
+{
+       struct hlist_head *head;
+       struct lttng_id_hash_node *e;
+       struct lttng_id_tracker_rcu *p = lf->p;
+       uint32_t hash = hash_32(id, 32);
+
+       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 (id == e->id) {
+                       id_tracker_del_node_rcu(e);
+                       return 0;
+               }
+       }
+       return -ENOENT; /* Not found */
+}
+
+static void lttng_id_tracker_rcu_destroy(struct lttng_id_tracker_rcu *p)
+{
+       int i;
+
+       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)
+                       id_tracker_del_node(e);
+       }
+       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/lttng-tracker-pid.c b/lttng-tracker-pid.c
deleted file mode 100644 (file)
index 747aec2..0000000
+++ /dev/null
@@ -1,145 +0,0 @@
-/* SPDX-License-Identifier: (GPL-2.0 or LGPL-2.1)
- *
- * lttng-tracker-pid.c
- *
- * LTTng Process ID tracking.
- *
- * Copyright (C) 2014 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
- */
-
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/err.h>
-#include <linux/seq_file.h>
-#include <linux/stringify.h>
-#include <linux/hash.h>
-#include <linux/rcupdate.h>
-
-#include <wrapper/tracepoint.h>
-#include <wrapper/rcu.h>
-#include <wrapper/list.h>
-#include <lttng-events.h>
-
-/*
- * Hash table is allocated and freed when there are no possible
- * concurrent lookups (ensured by the alloc/free caller). However,
- * there can be concurrent RCU lookups vs add/del operations.
- *
- * Concurrent updates of the PID hash table are forbidden: the caller
- * must ensure mutual exclusion. This is currently done by holding the
- * 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)
-{
-       return node->pid;
-}
-
-/*
- * 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.
- */
-bool lttng_pid_tracker_lookup(struct lttng_pid_tracker *lpf, int pid)
-{
-       struct hlist_head *head;
-       struct lttng_pid_hash_node *e;
-       uint32_t hash = hash_32(pid, 32);
-
-       head = &lpf->pid_hash[hash & (LTTNG_PID_TABLE_SIZE - 1)];
-       lttng_hlist_for_each_entry_rcu(e, head, hlist) {
-               if (pid == e->pid)
-                       return 1;       /* Found */
-       }
-       return 0;
-}
-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)
-{
-       struct hlist_head *head;
-       struct lttng_pid_hash_node *e;
-       uint32_t hash = hash_32(pid, 32);
-
-       head = &lpf->pid_hash[hash & (LTTNG_PID_TABLE_SIZE - 1)];
-       lttng_hlist_for_each_entry(e, head, hlist) {
-               if (pid == e->pid)
-                       return -EEXIST;
-       }
-       e = kmalloc(sizeof(struct lttng_pid_hash_node), GFP_KERNEL);
-       if (!e)
-               return -ENOMEM;
-       e->pid = pid;
-       hlist_add_head_rcu(&e->hlist, head);
-       return 0;
-}
-
-static
-void pid_tracker_del_node_rcu(struct lttng_pid_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
-        * 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
-        * want to afford adding a rcu_head field to those pid hash
-        * node.
-        */
-       synchronize_trace();
-       kfree(e);
-}
-
-/*
- * This removal is only used on destroy, so it does not need to support
- * concurrent RCU lookups.
- */
-static
-void pid_tracker_del_node(struct lttng_pid_hash_node *e)
-{
-       hlist_del(&e->hlist);
-       kfree(e);
-}
-
-int lttng_pid_tracker_del(struct lttng_pid_tracker *lpf, int pid)
-{
-       struct hlist_head *head;
-       struct lttng_pid_hash_node *e;
-       uint32_t hash = hash_32(pid, 32);
-
-       head = &lpf->pid_hash[hash & (LTTNG_PID_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);
-                       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)
-{
-       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;
-               struct hlist_node *tmp;
-
-               lttng_hlist_for_each_entry_safe(e, tmp, head, hlist)
-                       pid_tracker_del_node(e);
-       }
-       kfree(lpf);
-}
index 3fe9d995cf310bbc9d15b794b92892dd475c9afd..39454fb3d9c13d68fc4648aa135a1aacd224bb80 100644 (file)
@@ -11,6 +11,7 @@
 #include <linux/rculist.h>
 #include <asm/byteorder.h>
 #include <linux/swab.h>
+#include <linux/uidgid.h>
 
 #include <probes/lttng.h>
 #include <probes/lttng-types.h>
@@ -1127,7 +1128,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;                                                       \
@@ -1137,8 +1138,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(&lttng_dynamic_len_stack)->offset; \
        __dynamic_len_idx = __orig_dynamic_len_offset;                        \
@@ -1201,7 +1221,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;                                                       \
@@ -1211,8 +1231,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->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(&lttng_dynamic_len_stack)->offset; \
        __dynamic_len_idx = __orig_dynamic_len_offset;                        \
This page took 0.040777 seconds and 4 git commands to generate.