Signed-off-by: Francis Deslauriers <francis.deslauriers@efficios.com>
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
} __attribute__((packed));
struct lttng_kernel_uprobe {
} __attribute__((packed));
struct lttng_kernel_uprobe {
- char path[LTTNG_KERNEL_SYM_NAME_LEN];
uint64_t offset;
} __attribute__((packed));
uint64_t offset;
} __attribute__((packed));
smp_wmb();
ret = lttng_uprobes_register(event_param->name,
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)
event_param->u.uprobe.offset,
event);
if (ret)
#ifdef CONFIG_UPROBES
int lttng_uprobes_register(const char *name,
#ifdef CONFIG_UPROBES
int lttng_uprobes_register(const char *name,
uint64_t offset,
struct lttng_event *event);
void lttng_uprobes_unregister(struct lttng_event *event);
uint64_t offset,
struct lttng_event *event);
void lttng_uprobes_unregister(struct lttng_event *event);
#else
static inline
int lttng_uprobes_register(const char *name,
#else
static inline
int lttng_uprobes_register(const char *name,
uint64_t offset,
struct lttng_event *event)
{
uint64_t offset,
struct lttng_event *event)
{
struct {
unsigned long ip;
struct {
unsigned long ip;
if (unlikely(!ACCESS_ONCE(chan->session->active)))
return 0;
if (unlikely(!ACCESS_ONCE(chan->session->active)))
return 0;
/* Event payload. */
payload.ip = regs->ip;
/* 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);
lib_ring_buffer_align_ctx(&ctx, lttng_alignof(payload));
chan->ops->event_write(&ctx, &payload, sizeof(payload));
chan->ops->event_commit(&ctx);
+/*
+ * 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,
int lttng_uprobes_register(const char *name,
uint64_t offset,
struct lttng_event *event)
{
int ret;
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;
ret = lttng_create_uprobe_event(name, event);
if (ret)
goto error;
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;
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();
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);
ret = wrapper_uprobe_register(event->u.uprobe.inode,
event->u.uprobe.offset,
&event->u.uprobe.up_consumer);
register_error:
iput(event->u.uprobe.inode);
register_error:
iput(event->u.uprobe.inode);
kfree(event->desc->name);
kfree(event->desc);
error:
kfree(event->desc->name);
kfree(event->desc);
error: