uprobe: Receive file descriptor from session instead of path to file
authorFrancis Deslauriers <francis.deslauriers@efficios.com>
Tue, 27 Jun 2017 20:23:27 +0000 (16:23 -0400)
committerMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Mon, 27 Aug 2018 21:38:06 +0000 (17:38 -0400)
Signed-off-by: Francis Deslauriers <francis.deslauriers@efficios.com>
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
lttng-abi.h
lttng-events.c
lttng-events.h
probes/lttng-uprobes.c

index 24877dc863c6513c93221631239e35bffab6b6e9..762c10b0e44a23e96261680d8ee882731e07608f 100644 (file)
@@ -75,7 +75,7 @@ struct lttng_kernel_function_tracer {
 } __attribute__((packed));
 
 struct lttng_kernel_uprobe {
-       char path[LTTNG_KERNEL_SYM_NAME_LEN];
+       int fd;
        uint64_t offset;
 } __attribute__((packed));
 
index a3030533d1e62d1c01f4cc8b0db9fed4cffa7425..67ed16972a10fbdfe949f4abf8e57bf4a2be0bbd 100644 (file)
@@ -756,7 +756,7 @@ struct lttng_event *_lttng_event_create(struct lttng_channel *chan,
                smp_wmb();
 
                ret = lttng_uprobes_register(event_param->name,
-                               event_param->u.uprobe.path,
+                               event_param->u.uprobe.fd,
                                event_param->u.uprobe.offset,
                                event);
                if (ret)
index 4093bd8abd6a39567bd33213cb33746218c9f3f0..f6fe151886debe591ff295c800a80b5e5d81e5db 100644 (file)
@@ -779,7 +779,7 @@ void lttng_kprobes_destroy_private(struct lttng_event *event)
 
 #ifdef CONFIG_UPROBES
 int lttng_uprobes_register(const char *name,
-               const char *path,
+               int fd,
                uint64_t offset,
                struct lttng_event *event);
 void lttng_uprobes_unregister(struct lttng_event *event);
@@ -787,7 +787,7 @@ void lttng_uprobes_destroy_private(struct lttng_event *event);
 #else
 static inline
 int lttng_uprobes_register(const char *name,
-               const char *path,
+               int fd,
                uint64_t offset,
                struct lttng_event *event)
 {
index 0906992022897fca346e9ab937e51b8b2163c87a..1f549c2f34bb14660c3513953a5711c9aaddd693 100644 (file)
@@ -47,7 +47,7 @@ int lttng_uprobes_handler_pre(struct uprobe_consumer *uc, struct pt_regs *regs)
 
        struct {
                unsigned long ip;
-        } payload;
+       } payload;
 
        if (unlikely(!ACCESS_ONCE(chan->session->active)))
                return 0;
@@ -65,6 +65,7 @@ int lttng_uprobes_handler_pre(struct uprobe_consumer *uc, struct pt_regs *regs)
 
        /* Event payload. */
        payload.ip = regs->ip;
+
        lib_ring_buffer_align_ctx(&ctx, lttng_alignof(payload));
        chan->ops->event_write(&ctx, &payload, sizeof(payload));
        chan->ops->event_commit(&ctx);
@@ -119,38 +120,65 @@ error_str:
        return ret;
 }
 
+/*
+ * Returns the inode struct from the current task and an fd. The inode is
+ * grabbed by this function and must be put once we are done with it using
+ * iput().
+ */
+static struct inode *get_inode_from_fd(int fd)
+{
+       struct file *file;
+       struct inode *inode;
+
+       rcu_read_lock();
+       /*
+        * Returns the file backing the given fd. Needs to be done inside an RCU
+        * critical section.
+        */
+       file = fcheck(fd);
+       if (file == NULL) {
+               printk(KERN_WARNING "Cannot access file backing the fd(%d)\n", fd);
+               inode = NULL;
+               goto error;
+       }
+
+       /* Grab a reference on the inode. */
+       inode = igrab(file->f_path.dentry->d_inode);
+       if (inode == NULL)
+               printk(KERN_WARNING "Cannot grab a reference on the inode.\n");
+error:
+       rcu_read_unlock();
+       return inode;
+}
+
 int lttng_uprobes_register(const char *name,
-                          const char *path_name,
+                          int fd,
                           uint64_t offset,
                           struct lttng_event *event)
 {
        int ret;
-
-       /* Shoudl we fail if the path is empty, it should be checked before */
-       if (path_name[0] == '\0')
-               path_name = NULL;
+       struct inode *inode;
 
        ret = lttng_create_uprobe_event(name, event);
        if (ret)
                goto error;
 
+       inode = get_inode_from_fd(fd);
+       if (!inode) {
+               printk(KERN_WARNING "Cannot get inode from fd\n");
+               ret = -EBADF;
+               goto inode_error;
+       }
+
        memset(&event->u.uprobe.up_consumer, 0,
               sizeof(event->u.uprobe.up_consumer));
 
        event->u.uprobe.up_consumer.handler = lttng_uprobes_handler_pre;
-       if (path_name) {
-               struct path path;
-               ret = kern_path(path_name, LOOKUP_FOLLOW, &path);
-               if (ret)
-                       goto path_error;
-
-               event->u.uprobe.inode = igrab(path.dentry->d_inode);
-       }
+       event->u.uprobe.inode = inode;
        event->u.uprobe.offset = offset;
 
         /* Ensure the memory we just allocated don't trigger page faults. */
        wrapper_vmalloc_sync_all();
-       printk(KERN_WARNING "Registering probe on inode %lu and offset %llu\n", event->u.uprobe.inode->i_ino, event->u.uprobe.offset);
        ret = wrapper_uprobe_register(event->u.uprobe.inode,
                        event->u.uprobe.offset,
                        &event->u.uprobe.up_consumer);
@@ -164,7 +192,7 @@ int lttng_uprobes_register(const char *name,
 
 register_error:
        iput(event->u.uprobe.inode);
-path_error:
+inode_error:
        kfree(event->desc->name);
        kfree(event->desc);
 error:
This page took 0.028532 seconds and 4 git commands to generate.