X-Git-Url: http://git.lttng.org/?a=blobdiff_plain;f=lttng-abi.c;h=8073e9880ff109b1efdc27dd835b82b19b8f3c47;hb=bcde0d5b7da973a9372b3db4acc0b08b9589e05b;hp=c2560e0573c2a9a5827a8bfb10d18b7642c96f1a;hpb=3b731ab1a88c60e0a3a8eeddd225f751e821b1f3;p=lttng-modules.git diff --git a/lttng-abi.c b/lttng-abi.c index c2560e05..8073e988 100644 --- a/lttng-abi.c +++ b/lttng-abi.c @@ -43,6 +43,7 @@ #include #include #include +#include #include "wrapper/vmalloc.h" /* for wrapper_vmalloc_sync_all() */ #include "wrapper/ringbuffer/vfs.h" #include "wrapper/ringbuffer/backend.h" @@ -117,7 +118,7 @@ int lttng_abi_tracepoint_list(void) goto fd_error; } - tracepoint_list_file = anon_inode_getfile("[lttng_session]", + tracepoint_list_file = anon_inode_getfile("[lttng_tracepoint_list]", <tng_tracepoint_list_fops, NULL, O_RDWR); if (IS_ERR(tracepoint_list_file)) { @@ -142,6 +143,43 @@ fd_error: return ret; } +static +int lttng_abi_syscall_list(void) +{ + struct file *syscall_list_file; + int file_fd, ret; + + file_fd = get_unused_fd(); + if (file_fd < 0) { + ret = file_fd; + goto fd_error; + } + + syscall_list_file = anon_inode_getfile("[lttng_syscall_list]", + <tng_syscall_list_fops, + NULL, O_RDWR); + if (IS_ERR(syscall_list_file)) { + ret = PTR_ERR(syscall_list_file); + goto file_error; + } + ret = lttng_syscall_list_fops.open(NULL, syscall_list_file); + if (ret < 0) + goto open_error; + fd_install(file_fd, syscall_list_file); + if (file_fd < 0) { + ret = file_fd; + goto fd_error; + } + return file_fd; + +open_error: + fput(syscall_list_file); +file_error: + put_unused_fd(file_fd); +fd_error: + return ret; +} + static void lttng_abi_tracer_version(struct lttng_kernel_tracer_version *v) { @@ -248,6 +286,8 @@ long lttng_ioctl(struct file *file, unsigned int cmd, unsigned long arg) case LTTNG_KERNEL_OLD_TRACEPOINT_LIST: case LTTNG_KERNEL_TRACEPOINT_LIST: return lttng_abi_tracepoint_list(); + case LTTNG_KERNEL_SYSCALL_LIST: + return lttng_abi_syscall_list(); case LTTNG_KERNEL_OLD_WAIT_QUIESCENT: case LTTNG_KERNEL_WAIT_QUIESCENT: synchronize_trace(); @@ -548,23 +588,6 @@ unsigned int lttng_metadata_ring_buffer_poll(struct file *filp, return mask; } -static -int lttng_metadata_ring_buffer_ioctl_get_next_subbuf(struct file *filp, - unsigned int cmd, unsigned long arg) -{ - struct lttng_metadata_stream *stream = filp->private_data; - struct lib_ring_buffer *buf = stream->priv; - struct channel *chan = buf->backend.chan; - int ret; - - ret = lttng_metadata_output_channel(stream, chan); - if (ret > 0) { - lib_ring_buffer_switch_slow(buf, SWITCH_ACTIVE); - ret = 0; - } - return ret; -} - static void lttng_metadata_ring_buffer_ioctl_put_next_subbuf(struct file *filp, unsigned int cmd, unsigned long arg) @@ -585,9 +608,15 @@ long lttng_metadata_ring_buffer_ioctl(struct file *filp, switch (cmd) { case RING_BUFFER_GET_NEXT_SUBBUF: { - ret = lttng_metadata_ring_buffer_ioctl_get_next_subbuf(filp, - cmd, arg); - if (ret < 0) + struct lttng_metadata_stream *stream = filp->private_data; + struct lib_ring_buffer *buf = stream->priv; + struct channel *chan = buf->backend.chan; + + ret = lttng_metadata_output_channel(stream, chan); + if (ret > 0) { + lib_ring_buffer_switch_slow(buf, SWITCH_ACTIVE); + ret = 0; + } else if (ret < 0) goto err; break; } @@ -598,6 +627,21 @@ long lttng_metadata_ring_buffer_ioctl(struct file *filp, */ return -ENOSYS; } + case RING_BUFFER_FLUSH: + { + struct lttng_metadata_stream *stream = filp->private_data; + struct lib_ring_buffer *buf = stream->priv; + struct channel *chan = buf->backend.chan; + + /* + * Before doing the actual ring buffer flush, write up to one + * packet of metadata in the ring buffer. + */ + ret = lttng_metadata_output_channel(stream, chan); + if (ret < 0) + goto err; + break; + } default: break; } @@ -634,9 +678,15 @@ long lttng_metadata_ring_buffer_compat_ioctl(struct file *filp, switch (cmd) { case RING_BUFFER_GET_NEXT_SUBBUF: { - ret = lttng_metadata_ring_buffer_ioctl_get_next_subbuf(filp, - cmd, arg); - if (ret < 0) + struct lttng_metadata_stream *stream = filp->private_data; + struct lib_ring_buffer *buf = stream->priv; + struct channel *chan = buf->backend.chan; + + ret = lttng_metadata_output_channel(stream, chan); + if (ret > 0) { + lib_ring_buffer_switch_slow(buf, SWITCH_ACTIVE); + ret = 0; + } else if (ret < 0) goto err; break; } @@ -830,6 +880,7 @@ int lttng_abi_open_metadata_stream(struct file *channel_file) metadata_stream->priv = buf; stream_priv = metadata_stream; metadata_stream->transport = channel->transport; + mutex_init(&metadata_stream->lock); /* * Since life-time of metadata cache differs from that of @@ -902,8 +953,9 @@ int lttng_abi_create_event(struct file *channel_file, * will stay invariant for the rest of the session. */ event = lttng_event_create(channel, event_param, NULL, NULL); - if (!event) { - ret = -EINVAL; + WARN_ON_ONCE(!event); + if (IS_ERR(event)) { + ret = PTR_ERR(event); goto event_error; } event_file->private_data = event; @@ -912,15 +964,24 @@ int lttng_abi_create_event(struct file *channel_file, atomic_long_inc(&channel_file->f_count); break; case LTTNG_KERNEL_SYSCALL: - /* - * Only all-syscall tracing supported for now. - */ - if (event_param->name[0] != '\0') - return -EINVAL; ret = lttng_syscalls_register(channel, NULL); if (ret) goto fd_error; event_fd = 0; + if (event_param->u.syscall.enable) { + ret = lttng_syscall_filter_enable(channel, + event_param->name[0] == '\0' ? + NULL : event_param->name); + if (ret) + goto fd_error; + + } else { + ret = lttng_syscall_filter_disable(channel, + event_param->name[0] == '\0' ? + NULL : event_param->name); + if (ret) + goto fd_error; + } break; } return event_fd; @@ -1109,6 +1170,9 @@ old_ctx_end: case LTTNG_KERNEL_OLD_DISABLE: case LTTNG_KERNEL_DISABLE: return lttng_channel_disable(channel); + case LTTNG_KERNEL_SYSCALL_MASK: + return lttng_channel_syscall_mask(channel, + (struct lttng_kernel_syscall_mask __user *) arg); default: return -ENOIOCTLCMD; } @@ -1335,7 +1399,7 @@ static long lttng_stream_ring_buffer_ioctl(struct file *filp, struct lib_ring_buffer *buf = filp->private_data; struct channel *chan = buf->backend.chan; const struct lib_ring_buffer_config *config = &chan->backend.config; - struct lttng_channel *lttng_chan = channel_get_private(chan); + const struct lttng_channel_ops *ops = chan->backend.priv_ops; int ret; if (atomic_read(&chan->record_disabled)) @@ -1346,9 +1410,7 @@ static long lttng_stream_ring_buffer_ioctl(struct file *filp, { uint64_t ts; - if (!lttng_chan->ops) - goto error; - ret = lttng_chan->ops->timestamp_begin(config, buf, &ts); + ret = ops->timestamp_begin(config, buf, &ts); if (ret < 0) goto error; return put_u64(ts, arg); @@ -1357,9 +1419,7 @@ static long lttng_stream_ring_buffer_ioctl(struct file *filp, { uint64_t ts; - if (!lttng_chan->ops) - goto error; - ret = lttng_chan->ops->timestamp_end(config, buf, &ts); + ret = ops->timestamp_end(config, buf, &ts); if (ret < 0) goto error; return put_u64(ts, arg); @@ -1368,9 +1428,7 @@ static long lttng_stream_ring_buffer_ioctl(struct file *filp, { uint64_t ed; - if (!lttng_chan->ops) - goto error; - ret = lttng_chan->ops->events_discarded(config, buf, &ed); + ret = ops->events_discarded(config, buf, &ed); if (ret < 0) goto error; return put_u64(ed, arg); @@ -1379,9 +1437,7 @@ static long lttng_stream_ring_buffer_ioctl(struct file *filp, { uint64_t cs; - if (!lttng_chan->ops) - goto error; - ret = lttng_chan->ops->content_size(config, buf, &cs); + ret = ops->content_size(config, buf, &cs); if (ret < 0) goto error; return put_u64(cs, arg); @@ -1390,9 +1446,7 @@ static long lttng_stream_ring_buffer_ioctl(struct file *filp, { uint64_t ps; - if (!lttng_chan->ops) - goto error; - ret = lttng_chan->ops->packet_size(config, buf, &ps); + ret = ops->packet_size(config, buf, &ps); if (ret < 0) goto error; return put_u64(ps, arg); @@ -1401,13 +1455,20 @@ static long lttng_stream_ring_buffer_ioctl(struct file *filp, { uint64_t si; - if (!lttng_chan->ops) - goto error; - ret = lttng_chan->ops->stream_id(config, buf, &si); + ret = ops->stream_id(config, buf, &si); if (ret < 0) goto error; return put_u64(si, arg); } + case LTTNG_RING_BUFFER_GET_CURRENT_TIMESTAMP: + { + uint64_t ts; + + ret = ops->current_timestamp(config, buf, &ts); + if (ret < 0) + goto error; + return put_u64(ts, arg); + } default: return lib_ring_buffer_file_operations.unlocked_ioctl(filp, cmd, arg); @@ -1424,7 +1485,7 @@ static long lttng_stream_ring_buffer_compat_ioctl(struct file *filp, struct lib_ring_buffer *buf = filp->private_data; struct channel *chan = buf->backend.chan; const struct lib_ring_buffer_config *config = &chan->backend.config; - struct lttng_channel *lttng_chan = channel_get_private(chan); + const struct lttng_channel_ops *ops = chan->backend.priv_ops; int ret; if (atomic_read(&chan->record_disabled)) @@ -1435,9 +1496,7 @@ static long lttng_stream_ring_buffer_compat_ioctl(struct file *filp, { uint64_t ts; - if (!lttng_chan->ops) - goto error; - ret = lttng_chan->ops->timestamp_begin(config, buf, &ts); + ret = ops->timestamp_begin(config, buf, &ts); if (ret < 0) goto error; return put_u64(ts, arg); @@ -1446,9 +1505,7 @@ static long lttng_stream_ring_buffer_compat_ioctl(struct file *filp, { uint64_t ts; - if (!lttng_chan->ops) - goto error; - ret = lttng_chan->ops->timestamp_end(config, buf, &ts); + ret = ops->timestamp_end(config, buf, &ts); if (ret < 0) goto error; return put_u64(ts, arg); @@ -1457,9 +1514,7 @@ static long lttng_stream_ring_buffer_compat_ioctl(struct file *filp, { uint64_t ed; - if (!lttng_chan->ops) - goto error; - ret = lttng_chan->ops->events_discarded(config, buf, &ed); + ret = ops->events_discarded(config, buf, &ed); if (ret < 0) goto error; return put_u64(ed, arg); @@ -1468,9 +1523,7 @@ static long lttng_stream_ring_buffer_compat_ioctl(struct file *filp, { uint64_t cs; - if (!lttng_chan->ops) - goto error; - ret = lttng_chan->ops->content_size(config, buf, &cs); + ret = ops->content_size(config, buf, &cs); if (ret < 0) goto error; return put_u64(cs, arg); @@ -1479,9 +1532,7 @@ static long lttng_stream_ring_buffer_compat_ioctl(struct file *filp, { uint64_t ps; - if (!lttng_chan->ops) - goto error; - ret = lttng_chan->ops->packet_size(config, buf, &ps); + ret = ops->packet_size(config, buf, &ps); if (ret < 0) goto error; return put_u64(ps, arg); @@ -1490,13 +1541,20 @@ static long lttng_stream_ring_buffer_compat_ioctl(struct file *filp, { uint64_t si; - if (!lttng_chan->ops) - goto error; - ret = lttng_chan->ops->stream_id(config, buf, &si); + ret = ops->stream_id(config, buf, &si); if (ret < 0) goto error; return put_u64(si, arg); } + case LTTNG_RING_BUFFER_GET_CURRENT_TIMESTAMP: + { + uint64_t ts; + + ret = ops->current_timestamp(config, buf, &ts); + if (ret < 0) + goto error; + return put_u64(ts, arg); + } default: return lib_ring_buffer_file_operations.compat_ioctl(filp, cmd, arg); @@ -1549,7 +1607,8 @@ error: return ret; } -void __exit lttng_abi_exit(void) +/* No __exit annotation because used by init error path too. */ +void lttng_abi_exit(void) { if (lttng_proc_dentry) remove_proc_entry("lttng", NULL);