X-Git-Url: https://git.lttng.org/?a=blobdiff_plain;f=src%2Flttng-abi.c;h=d660ad470c7653801159a61b35059f2a2af183be;hb=e2d5dbc7d09c7aa4f7c391fcdd4dfc95ba1ed326;hp=4e0003be6f8f0aabb6042ec084102d459288b163;hpb=606828e401c405619a0c7249e8c7e3291cc1cb45;p=lttng-modules.git diff --git a/src/lttng-abi.c b/src/lttng-abi.c index 4e0003be..d660ad47 100644 --- a/src/lttng-abi.c +++ b/src/lttng-abi.c @@ -65,7 +65,8 @@ static const struct file_operations lttng_session_fops; static const struct file_operations lttng_event_notifier_group_fops; static const struct file_operations lttng_channel_fops; static const struct file_operations lttng_metadata_fops; -static const struct file_operations lttng_event_fops; +static const struct file_operations lttng_event_recorder_event_fops; +static const struct file_operations lttng_event_recorder_enabler_fops; static struct file_operations lttng_stream_ring_buffer_file_operations; static int put_u64(uint64_t val, unsigned long arg); @@ -1775,6 +1776,7 @@ static int lttng_abi_create_event(struct file *channel_file, struct lttng_kernel_abi_event *event_param) { + const struct file_operations *fops; struct lttng_channel *channel = channel_file->private_data; int event_fd, ret; struct file *event_file; @@ -1795,14 +1797,31 @@ int lttng_abi_create_event(struct file *channel_file, default: break; } + + switch (event_param->instrumentation) { + case LTTNG_KERNEL_ABI_TRACEPOINT: /* Fall-through */ + case LTTNG_KERNEL_ABI_SYSCALL: + fops = <tng_event_recorder_enabler_fops; + break; + case LTTNG_KERNEL_ABI_KPROBE: /* Fall-through */ + case LTTNG_KERNEL_ABI_KRETPROBE: /* Fall-through */ + case LTTNG_KERNEL_ABI_UPROBE: + fops = <tng_event_recorder_event_fops; + break; + + case LTTNG_KERNEL_ABI_FUNCTION: /* Fall-through */ + case LTTNG_KERNEL_ABI_NOOP: /* Fall-through */ + default: + return -EINVAL; + } + event_fd = lttng_get_unused_fd(); if (event_fd < 0) { ret = event_fd; goto fd_error; } event_file = anon_inode_getfile("[lttng_event]", - <tng_event_fops, - NULL, O_RDWR); + fops, NULL, O_RDWR); if (IS_ERR(event_file)) { ret = PTR_ERR(event_file); goto file_error; @@ -1837,19 +1856,18 @@ int lttng_abi_create_event(struct file *channel_file, break; } - case LTTNG_KERNEL_ABI_KPROBE: /* Fall-through */ + case LTTNG_KERNEL_ABI_KPROBE: /* Fall-through */ case LTTNG_KERNEL_ABI_KRETPROBE: /* Fall-through */ case LTTNG_KERNEL_ABI_UPROBE: { - struct lttng_event *event; + struct lttng_kernel_event_recorder *event; /* * We tolerate no failure path after event creation. It * will stay invariant for the rest of the session. */ - event = lttng_event_create(channel, event_param, - NULL, NULL, - event_param->instrumentation); + event = lttng_kernel_event_recorder_create(channel, event_param, + NULL, event_param->instrumentation); WARN_ON_ONCE(!event); if (IS_ERR(event)) { ret = PTR_ERR(event); @@ -1859,7 +1877,7 @@ int lttng_abi_create_event(struct file *channel_file, break; } - case LTTNG_KERNEL_ABI_FUNCTION: /* Fall-through */ + case LTTNG_KERNEL_ABI_FUNCTION: /* Fall-through */ case LTTNG_KERNEL_ABI_NOOP: /* Fall-through */ default: ret = -EINVAL; @@ -1880,116 +1898,87 @@ fd_error: } static -long lttng_event_notifier_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +long lttng_event_notifier_event_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { - struct lttng_event_notifier *event_notifier; - struct lttng_event_notifier_enabler *event_notifier_enabler; - enum lttng_event_type *evtype = file->private_data; + struct lttng_kernel_event_notifier *event_notifier = file->private_data; switch (cmd) { case LTTNG_KERNEL_ABI_ENABLE: - switch (*evtype) { - case LTTNG_TYPE_EVENT: - event_notifier = file->private_data; - return lttng_event_notifier_enable(event_notifier); - case LTTNG_TYPE_ENABLER: - event_notifier_enabler = file->private_data; - return lttng_event_notifier_enabler_enable(event_notifier_enabler); - default: - WARN_ON_ONCE(1); - return -ENOSYS; - } + return lttng_event_notifier_enable(event_notifier); case LTTNG_KERNEL_ABI_DISABLE: - switch (*evtype) { - case LTTNG_TYPE_EVENT: - event_notifier = file->private_data; - return lttng_event_notifier_disable(event_notifier); - case LTTNG_TYPE_ENABLER: - event_notifier_enabler = file->private_data; - return lttng_event_notifier_enabler_disable(event_notifier_enabler); - default: - WARN_ON_ONCE(1); - return -ENOSYS; - } + return lttng_event_notifier_disable(event_notifier); case LTTNG_KERNEL_ABI_FILTER: - switch (*evtype) { - case LTTNG_TYPE_EVENT: - return -EINVAL; - case LTTNG_TYPE_ENABLER: - event_notifier_enabler = file->private_data; - return lttng_event_notifier_enabler_attach_filter_bytecode( - event_notifier_enabler, - (struct lttng_kernel_abi_filter_bytecode __user *) arg); - default: - WARN_ON_ONCE(1); - return -ENOSYS; - } - + return -EINVAL; case LTTNG_KERNEL_ABI_CAPTURE: - switch (*evtype) { - case LTTNG_TYPE_EVENT: - return -EINVAL; - case LTTNG_TYPE_ENABLER: - event_notifier_enabler = file->private_data; - return lttng_event_notifier_enabler_attach_capture_bytecode( - event_notifier_enabler, - (struct lttng_kernel_abi_capture_bytecode __user *) arg); - default: - WARN_ON_ONCE(1); - return -ENOSYS; - } + return -EINVAL; case LTTNG_KERNEL_ABI_ADD_CALLSITE: - switch (*evtype) { - case LTTNG_TYPE_EVENT: - event_notifier = file->private_data; - return lttng_event_notifier_add_callsite(event_notifier, - (struct lttng_kernel_abi_event_callsite __user *) arg); - case LTTNG_TYPE_ENABLER: - return -EINVAL; - default: - WARN_ON_ONCE(1); - return -ENOSYS; - } + return lttng_event_add_callsite(&event_notifier->parent, + (struct lttng_kernel_abi_event_callsite __user *) arg); default: return -ENOIOCTLCMD; } } static -int lttng_event_notifier_release(struct inode *inode, struct file *file) +long lttng_event_notifier_enabler_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { - struct lttng_event_notifier *event_notifier; - struct lttng_event_notifier_enabler *event_notifier_enabler; - enum lttng_event_type *evtype = file->private_data; - - if (!evtype) - return 0; + struct lttng_event_notifier_enabler *event_notifier_enabler = file->private_data; - switch (*evtype) { - case LTTNG_TYPE_EVENT: - event_notifier = file->private_data; - if (event_notifier) - fput(event_notifier->group->file); - break; - case LTTNG_TYPE_ENABLER: - event_notifier_enabler = file->private_data; - if (event_notifier_enabler) - fput(event_notifier_enabler->group->file); - break; + switch (cmd) { + case LTTNG_KERNEL_ABI_ENABLE: + return lttng_event_notifier_enabler_enable(event_notifier_enabler); + case LTTNG_KERNEL_ABI_DISABLE: + return lttng_event_notifier_enabler_disable(event_notifier_enabler); + case LTTNG_KERNEL_ABI_FILTER: + return lttng_event_notifier_enabler_attach_filter_bytecode( + event_notifier_enabler, + (struct lttng_kernel_abi_filter_bytecode __user *) arg); + case LTTNG_KERNEL_ABI_CAPTURE: + return lttng_event_notifier_enabler_attach_capture_bytecode( + event_notifier_enabler, + (struct lttng_kernel_abi_capture_bytecode __user *) arg); + case LTTNG_KERNEL_ABI_ADD_CALLSITE: + return -EINVAL; default: - WARN_ON_ONCE(1); - break; + return -ENOIOCTLCMD; } +} +static +int lttng_event_notifier_event_release(struct inode *inode, struct file *file) +{ + struct lttng_kernel_event_notifier *event_notifier = file->private_data; + + if (event_notifier) + fput(event_notifier->priv->group->file); return 0; } -static const struct file_operations lttng_event_notifier_fops = { +static +int lttng_event_notifier_enabler_release(struct inode *inode, struct file *file) +{ + struct lttng_event_notifier_enabler *event_notifier_enabler = file->private_data; + + if (event_notifier_enabler) + fput(event_notifier_enabler->group->file); + return 0; +} + +static const struct file_operations lttng_event_notifier_event_fops = { + .owner = THIS_MODULE, + .release = lttng_event_notifier_event_release, + .unlocked_ioctl = lttng_event_notifier_event_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = lttng_event_notifier_event_ioctl, +#endif +}; + +static const struct file_operations lttng_event_notifier_enabler_fops = { .owner = THIS_MODULE, - .release = lttng_event_notifier_release, - .unlocked_ioctl = lttng_event_notifier_ioctl, + .release = lttng_event_notifier_enabler_release, + .unlocked_ioctl = lttng_event_notifier_enabler_ioctl, #ifdef CONFIG_COMPAT - .compat_ioctl = lttng_event_notifier_ioctl, + .compat_ioctl = lttng_event_notifier_enabler_ioctl, #endif }; @@ -1999,6 +1988,7 @@ int lttng_abi_create_event_notifier(struct file *event_notifier_group_file, { struct lttng_event_notifier_group *event_notifier_group = event_notifier_group_file->private_data; + const struct file_operations *fops; int event_notifier_fd, ret; struct file *event_notifier_file; void *priv; @@ -2021,6 +2011,24 @@ int lttng_abi_create_event_notifier(struct file *event_notifier_group_file, goto inval_instr; } + switch (event_notifier_param->event.instrumentation) { + case LTTNG_KERNEL_ABI_TRACEPOINT: /* Fall-through */ + case LTTNG_KERNEL_ABI_SYSCALL: + fops = <tng_event_notifier_enabler_fops; + break; + case LTTNG_KERNEL_ABI_KPROBE: /* Fall-through */ + case LTTNG_KERNEL_ABI_KRETPROBE: /* Fall-through */ + case LTTNG_KERNEL_ABI_UPROBE: + fops = <tng_event_notifier_event_fops; + break; + + case LTTNG_KERNEL_ABI_FUNCTION: /* Fall-through */ + case LTTNG_KERNEL_ABI_NOOP: /* Fall-through */ + default: + ret = -EINVAL; + goto inval_instr; + } + event_notifier_param->event.name[LTTNG_KERNEL_ABI_SYM_NAME_LEN - 1] = '\0'; event_notifier_fd = lttng_get_unused_fd(); @@ -2030,8 +2038,7 @@ int lttng_abi_create_event_notifier(struct file *event_notifier_group_file, } event_notifier_file = anon_inode_getfile("[lttng_event_notifier]", - <tng_event_notifier_fops, - NULL, O_RDWR); + fops, NULL, O_RDWR); if (IS_ERR(event_notifier_file)) { ret = PTR_ERR(event_notifier_file); goto file_error; @@ -2072,11 +2079,11 @@ int lttng_abi_create_event_notifier(struct file *event_notifier_group_file, break; } - case LTTNG_KERNEL_ABI_KPROBE: /* Fall-through */ + case LTTNG_KERNEL_ABI_KPROBE: /* Fall-through */ case LTTNG_KERNEL_ABI_KRETPROBE: /* Fall-through */ case LTTNG_KERNEL_ABI_UPROBE: { - struct lttng_event_notifier *event_notifier; + struct lttng_kernel_event_notifier *event_notifier; /* * We tolerate no failure path after event notifier creation. @@ -2086,7 +2093,7 @@ int lttng_abi_create_event_notifier(struct file *event_notifier_group_file, event_notifier_param->event.token, event_notifier_param->error_counter_index, event_notifier_group, - event_notifier_param, NULL, + event_notifier_param, event_notifier_param->event.instrumentation); WARN_ON_ONCE(!event_notifier); if (IS_ERR(event_notifier)) { @@ -2097,7 +2104,7 @@ int lttng_abi_create_event_notifier(struct file *event_notifier_group_file, break; } - case LTTNG_KERNEL_ABI_FUNCTION: /* Fall-through */ + case LTTNG_KERNEL_ABI_FUNCTION: /* Fall-through */ case LTTNG_KERNEL_ABI_NOOP: /* Fall-through */ default: ret = -EINVAL; @@ -2558,7 +2565,7 @@ static const struct file_operations lttng_metadata_fops = { }; /** - * lttng_event_ioctl - lttng syscall through ioctl + * lttng_event_recorder_event_ioctl - lttng syscall through ioctl * * @file: the file * @cmd: the command @@ -2573,11 +2580,9 @@ static const struct file_operations lttng_metadata_fops = { * Disable recording for this event (strong disable) */ static -long lttng_event_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +long lttng_event_recorder_event_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { - struct lttng_event *event; - struct lttng_event_enabler *event_enabler; - enum lttng_event_type *evtype = file->private_data; + struct lttng_kernel_event_recorder *event_recorder = file->private_data; switch (cmd) { case LTTNG_KERNEL_ABI_OLD_CONTEXT: @@ -2592,98 +2597,103 @@ long lttng_event_ioctl(struct file *file, unsigned int cmd, unsigned long arg) } case LTTNG_KERNEL_ABI_OLD_ENABLE: case LTTNG_KERNEL_ABI_ENABLE: - switch (*evtype) { - case LTTNG_TYPE_EVENT: - event = file->private_data; - return lttng_event_enable(event); - case LTTNG_TYPE_ENABLER: - event_enabler = file->private_data; - return lttng_event_enabler_enable(event_enabler); - default: - WARN_ON_ONCE(1); - return -ENOSYS; - } + return lttng_event_enable(event_recorder); case LTTNG_KERNEL_ABI_OLD_DISABLE: case LTTNG_KERNEL_ABI_DISABLE: - switch (*evtype) { - case LTTNG_TYPE_EVENT: - event = file->private_data; - return lttng_event_disable(event); - case LTTNG_TYPE_ENABLER: - event_enabler = file->private_data; - return lttng_event_enabler_disable(event_enabler); - default: - WARN_ON_ONCE(1); - return -ENOSYS; - } + return lttng_event_disable(event_recorder); case LTTNG_KERNEL_ABI_FILTER: - switch (*evtype) { - case LTTNG_TYPE_EVENT: - return -EINVAL; - case LTTNG_TYPE_ENABLER: - { - event_enabler = file->private_data; - return lttng_event_enabler_attach_filter_bytecode( - event_enabler, - (struct lttng_kernel_abi_filter_bytecode __user *) arg); - } - default: - WARN_ON_ONCE(1); - return -ENOSYS; - } + return -EINVAL; case LTTNG_KERNEL_ABI_ADD_CALLSITE: - switch (*evtype) { - case LTTNG_TYPE_EVENT: - event = file->private_data; - return lttng_event_add_callsite(event, - (struct lttng_kernel_abi_event_callsite __user *) arg); - case LTTNG_TYPE_ENABLER: - return -EINVAL; - default: - WARN_ON_ONCE(1); - return -ENOSYS; - } + return lttng_event_add_callsite(&event_recorder->parent, + (struct lttng_kernel_abi_event_callsite __user *) arg); default: return -ENOIOCTLCMD; } } +/** + * lttng_event_recorder_enabler_ioctl - lttng syscall through ioctl + * + * @file: the file + * @cmd: the command + * @arg: command arg + * + * This ioctl implements lttng commands: + * LTTNG_KERNEL_ABI_CONTEXT + * Prepend a context field to each record of this event + * LTTNG_KERNEL_ABI_ENABLE + * Enable recording for this event (weak enable) + * LTTNG_KERNEL_ABI_DISABLE + * Disable recording for this event (strong disable) + */ static -int lttng_event_release(struct inode *inode, struct file *file) +long lttng_event_recorder_enabler_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { - struct lttng_event *event; - struct lttng_event_enabler *event_enabler; - enum lttng_event_type *evtype = file->private_data; - - if (!evtype) - return 0; + struct lttng_event_enabler *event_enabler = file->private_data; - switch (*evtype) { - case LTTNG_TYPE_EVENT: - event = file->private_data; - if (event) - fput(event->chan->file); - break; - case LTTNG_TYPE_ENABLER: - event_enabler = file->private_data; - if (event_enabler) - fput(event_enabler->chan->file); - break; + switch (cmd) { + case LTTNG_KERNEL_ABI_OLD_CONTEXT: + { + /* Not implemented */ + return -ENOSYS; + } + case LTTNG_KERNEL_ABI_CONTEXT: + { + /* Not implemented */ + return -ENOSYS; + } + case LTTNG_KERNEL_ABI_OLD_ENABLE: + case LTTNG_KERNEL_ABI_ENABLE: + return lttng_event_enabler_enable(event_enabler); + case LTTNG_KERNEL_ABI_OLD_DISABLE: + case LTTNG_KERNEL_ABI_DISABLE: + return lttng_event_enabler_disable(event_enabler); + case LTTNG_KERNEL_ABI_FILTER: + return lttng_event_enabler_attach_filter_bytecode( + event_enabler, + (struct lttng_kernel_abi_filter_bytecode __user *) arg); + case LTTNG_KERNEL_ABI_ADD_CALLSITE: + return -EINVAL; default: - WARN_ON_ONCE(1); - break; + return -ENOIOCTLCMD; } +} + +static +int lttng_event_recorder_event_release(struct inode *inode, struct file *file) +{ + struct lttng_kernel_event_recorder *event = file->private_data; + + if (event) + fput(event->chan->file); + return 0; +} +static +int lttng_event_recorder_enabler_release(struct inode *inode, struct file *file) +{ + struct lttng_event_enabler *event_enabler = file->private_data; + + if (event_enabler) + fput(event_enabler->chan->file); return 0; } -/* TODO: filter control ioctl */ -static const struct file_operations lttng_event_fops = { +static const struct file_operations lttng_event_recorder_event_fops = { + .owner = THIS_MODULE, + .release = lttng_event_recorder_event_release, + .unlocked_ioctl = lttng_event_recorder_event_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = lttng_event_recorder_event_ioctl, +#endif +}; + +static const struct file_operations lttng_event_recorder_enabler_fops = { .owner = THIS_MODULE, - .release = lttng_event_release, - .unlocked_ioctl = lttng_event_ioctl, + .release = lttng_event_recorder_enabler_release, + .unlocked_ioctl = lttng_event_recorder_enabler_ioctl, #ifdef CONFIG_COMPAT - .compat_ioctl = lttng_event_ioctl, + .compat_ioctl = lttng_event_recorder_enabler_ioctl, #endif };