X-Git-Url: http://git.liburcu.org/?a=blobdiff_plain;f=src%2Flib%2Flttng-ust-ctl%2Fustctl.c;h=784cb75db0b46a7c42a9b506199a3e10e2baf343;hb=2722f20cbda88b5f6250213a7be8412c19a11e8a;hp=429b693d9acd2ac22318713700eea9b91e4c3cff;hpb=249cffb5cdf9cff45298a44580b24d4dd9d63ba0;p=lttng-ust.git diff --git a/src/lib/lttng-ust-ctl/ustctl.c b/src/lib/lttng-ust-ctl/ustctl.c index 429b693d..784cb75d 100644 --- a/src/lib/lttng-ust-ctl/ustctl.c +++ b/src/lib/lttng-ust-ctl/ustctl.c @@ -17,6 +17,8 @@ #include #include #include +#include +#include #include "common/logging.h" #include "common/ustcomm.h" @@ -27,11 +29,10 @@ #include "common/ringbuffer/frontend.h" #include "common/events.h" #include "common/wait.h" -#include "lib/lttng-ust/lttng-rb-clients.h" -#include "common/clock.h" +#include "common/ringbuffer-clients/clients.h" #include "common/getenv.h" -#include "lib/lttng-ust/lttng-tracer-core.h" -#include "lib/lttng-ust/lttng-counter-client.h" +#include "common/tracer.h" +#include "common/counter-clients/clients.h" #include "common/smp.h" #include "common/counter/counter.h" @@ -63,6 +64,7 @@ struct lttng_ust_ctl_consumer_stream { int shm_fd, wait_fd, wakeup_fd; int cpu; uint64_t memory_map_size; + void *memory_map_addr; }; #define LTTNG_UST_CTL_COUNTER_ATTR_DIMENSION_MAX 8 @@ -84,6 +86,67 @@ struct lttng_ust_ctl_daemon_counter { struct lttng_ust_ctl_counter_attr *attr; /* initial attributes */ }; +/* + * Evaluates to false if transaction begins, true if it has failed due to SIGBUS. + * The entire transaction must complete before the current function returns. + * A transaction can contain 0 or more tracked ranges as sigbus begin/end pairs. + */ +#define sigbus_begin() \ +({ \ + assert(!lttng_ust_sigbus_state.jmp_ready); \ + if (!lttng_ust_sigbus_state.head.next) { \ + /* \ + * Lazy init because static list initialisation is \ + * problematic for TLS variable. \ + */ \ + CDS_INIT_LIST_HEAD(<tng_ust_sigbus_state.head); \ + } \ + if (sigsetjmp(lttng_ust_sigbus_state.sj_env, 1)) { \ + /* SIGBUS. */ \ + CMM_STORE_SHARED(lttng_ust_sigbus_state.jmp_ready, 0); \ + true; \ + } \ + cmm_barrier(); \ + CMM_STORE_SHARED(lttng_ust_sigbus_state.jmp_ready, 1); \ + false; \ +}) + +static void sigbus_end(void) +{ + assert(lttng_ust_sigbus_state.jmp_ready); + cmm_barrier(); + CMM_STORE_SHARED(lttng_ust_sigbus_state.jmp_ready, 0); +} + +static +void lttng_ust_sigbus_add_range(struct lttng_ust_sigbus_range *range, void *start, size_t len) +{ + range->start = start; + range->end = (char *)start + len; + cds_list_add_rcu(&range->node, <tng_ust_sigbus_state.head); + cmm_barrier(); +} + +static +void lttng_ust_sigbus_del_range(struct lttng_ust_sigbus_range *range) +{ + cmm_barrier(); + cds_list_del_rcu(&range->node); +} + +void lttng_ust_ctl_sigbus_handle(void *addr) +{ + struct lttng_ust_sigbus_range *range; + + if (!CMM_LOAD_SHARED(lttng_ust_sigbus_state.jmp_ready)) + return; + cds_list_for_each_entry_rcu(range, <tng_ust_sigbus_state.head, node) { + if (addr < range->start || addr >= range->end) + continue; + siglongjmp(lttng_ust_sigbus_state.sj_env, 1); + } +} + int lttng_ust_ctl_release_handle(int sock, int handle) { struct ustcomm_ust_msg lum; @@ -249,6 +312,17 @@ int lttng_ust_ctl_create_event(int sock, struct lttng_ust_abi_event *ev, return 0; } +/* + * Protocol for LTTNG_UST_ABI_CONTEXT command: + * + * - send: struct ustcomm_ust_msg + * - send: var len ctx_name + * - receive: struct ustcomm_ust_reply + * + * TODO: At the next breaking protocol bump, we should indicate the total + * command message length as part of a message header so that the protocol can + * recover from invalid command errors. + */ int lttng_ust_ctl_add_context(int sock, struct lttng_ust_context_attr *ctx, struct lttng_ust_abi_object_data *obj_data, struct lttng_ust_abi_object_data **_context_data) @@ -320,6 +394,13 @@ int lttng_ust_ctl_add_context(int sock, struct lttng_ust_context_attr *ctx, } ret = ustcomm_recv_app_reply(sock, &lur, lum.handle, lum.cmd); if (ret < 0) { + if (ret == -EINVAL) { + /* + * Command unknown from remote end. The communication socket is + * now out-of-sync and needs to be shutdown. + */ + (void) ustcomm_shutdown_unix_sock(sock); + } goto end; } context_data->handle = -1; @@ -332,6 +413,17 @@ end: return ret; } +/* + * Protocol for LTTNG_UST_ABI_FILTER command: + * + * - send: struct ustcomm_ust_msg + * - send: var len bytecode + * - receive: struct ustcomm_ust_reply + * + * TODO: At the next breaking protocol bump, we should indicate the total + * command message length as part of a message header so that the protocol can + * recover from invalid command errors. + */ int lttng_ust_ctl_set_filter(int sock, struct lttng_ust_abi_filter_bytecode *bytecode, struct lttng_ust_abi_object_data *obj_data) { @@ -360,9 +452,25 @@ int lttng_ust_ctl_set_filter(int sock, struct lttng_ust_abi_filter_bytecode *byt } if (ret != bytecode->len) return -EINVAL; - return ustcomm_recv_app_reply(sock, &lur, lum.handle, lum.cmd); + ret = ustcomm_recv_app_reply(sock, &lur, lum.handle, lum.cmd); + if (ret == -EINVAL) { + /* + * Command unknown from remote end. The communication socket is + * now out-of-sync and needs to be shutdown. + */ + (void) ustcomm_shutdown_unix_sock(sock); + } + return ret; } +/* + * Protocol for LTTNG_UST_ABI_CAPTURE command: + * + * - send: struct ustcomm_ust_msg + * - receive: struct ustcomm_ust_reply + * - send: var len bytecode + * - receive: struct ustcomm_ust_reply (actual command return code) + */ int lttng_ust_ctl_set_capture(int sock, struct lttng_ust_abi_capture_bytecode *bytecode, struct lttng_ust_abi_object_data *obj_data) { @@ -380,7 +488,7 @@ int lttng_ust_ctl_set_capture(int sock, struct lttng_ust_abi_capture_bytecode *b lum.u.capture.reloc_offset = bytecode->reloc_offset; lum.u.capture.seqnum = bytecode->seqnum; - ret = ustcomm_send_app_msg(sock, &lum); + ret = ustcomm_send_app_cmd(sock, &lum, &lur); if (ret) return ret; /* send var len bytecode */ @@ -394,6 +502,17 @@ int lttng_ust_ctl_set_capture(int sock, struct lttng_ust_abi_capture_bytecode *b return ustcomm_recv_app_reply(sock, &lur, lum.handle, lum.cmd); } +/* + * Protocol for LTTNG_UST_ABI_EXCLUSION command: + * + * - send: struct ustcomm_ust_msg + * - send: var len exclusion names + * - receive: struct ustcomm_ust_reply + * + * TODO: At the next breaking protocol bump, we should indicate the total + * command message length as part of a message header so that the protocol can + * recover from invalid command errors. + */ int lttng_ust_ctl_set_exclusion(int sock, struct lttng_ust_abi_event_exclusion *exclusion, struct lttng_ust_abi_object_data *obj_data) { @@ -425,7 +544,15 @@ int lttng_ust_ctl_set_exclusion(int sock, struct lttng_ust_abi_event_exclusion * if (ret != exclusion->count * LTTNG_UST_ABI_SYM_NAME_LEN) { return -EINVAL; } - return ustcomm_recv_app_reply(sock, &lur, lum.handle, lum.cmd); + ret = ustcomm_recv_app_reply(sock, &lur, lum.handle, lum.cmd); + if (ret == -EINVAL) { + /* + * Command unknown from remote end. The communication socket is + * now out-of-sync and needs to be shutdown. + */ + (void) ustcomm_shutdown_unix_sock(sock); + } + return ret; } /* Enable event, channel and session ioctl */ @@ -484,6 +611,14 @@ int lttng_ust_ctl_stop_session(int sock, int handle) return lttng_ust_ctl_disable(sock, &obj); } +/* + * Protocol for LTTNG_UST_ABI_EVENT_NOTIFIER_GROUP_CREATE command: + * + * - send: struct ustcomm_ust_msg + * - receive: struct ustcomm_ust_reply + * - send: file descriptor + * - receive: struct ustcomm_ust_reply (actual command return code) + */ int lttng_ust_ctl_create_event_notifier_group(int sock, int pipe_fd, struct lttng_ust_abi_object_data **_event_notifier_group_data) { @@ -506,7 +641,7 @@ int lttng_ust_ctl_create_event_notifier_group(int sock, int pipe_fd, lum.handle = LTTNG_UST_ABI_ROOT_HANDLE; lum.cmd = LTTNG_UST_ABI_EVENT_NOTIFIER_GROUP_CREATE; - ret = ustcomm_send_app_msg(sock, &lum); + ret = ustcomm_send_app_cmd(sock, &lum, &lur); if (ret) goto error; @@ -535,6 +670,14 @@ end: return ret; } +/* + * Protocol for LTTNG_UST_ABI_EVENT_NOTIFIER_CREATE command: + * + * - send: struct ustcomm_ust_msg + * - receive: struct ustcomm_ust_reply + * - send: struct lttng_ust_abi_event_notifier + * - receive: struct ustcomm_ust_reply (actual command return code) + */ int lttng_ust_ctl_create_event_notifier(int sock, struct lttng_ust_abi_event_notifier *event_notifier, struct lttng_ust_abi_object_data *event_notifier_group, struct lttng_ust_abi_object_data **_event_notifier_data) @@ -559,7 +702,7 @@ int lttng_ust_ctl_create_event_notifier(int sock, struct lttng_ust_abi_event_not lum.cmd = LTTNG_UST_ABI_EVENT_NOTIFIER_CREATE; lum.u.event_notifier.len = sizeof(*event_notifier); - ret = ustcomm_send_app_msg(sock, &lum); + ret = ustcomm_send_app_cmd(sock, &lum, &lur); if (ret) { free(event_notifier_data); return ret; @@ -985,6 +1128,17 @@ error_alloc: return ret; } +/* + * Protocol for LTTNG_UST_ABI_CHANNEL command: + * + * - send: struct ustcomm_ust_msg + * - send: file descriptors and channel data + * - receive: struct ustcomm_ust_reply + * + * TODO: At the next breaking protocol bump, we should indicate the total + * command message length as part of a message header so that the protocol can + * recover from invalid command errors. + */ int lttng_ust_ctl_send_channel_to_ust(int sock, int session_handle, struct lttng_ust_abi_object_data *channel_data) { @@ -1015,10 +1169,27 @@ int lttng_ust_ctl_send_channel_to_ust(int sock, int session_handle, ret = ustcomm_recv_app_reply(sock, &lur, lum.handle, lum.cmd); if (!ret) { channel_data->handle = lur.ret_val; + } else if (ret == -EINVAL) { + /* + * Command unknown from remote end. The communication socket is + * now out-of-sync and needs to be shutdown. + */ + (void) ustcomm_shutdown_unix_sock(sock); } return ret; } +/* + * Protocol for LTTNG_UST_ABI_STREAM command: + * + * - send: struct ustcomm_ust_msg + * - send: file descriptors and stream data + * - receive: struct ustcomm_ust_reply + * + * TODO: At the next breaking protocol bump, we should indicate the total + * command message length as part of a message header so that the protocol can + * recover from invalid command errors. + */ int lttng_ust_ctl_send_stream_to_ust(int sock, struct lttng_ust_abi_object_data *channel_data, struct lttng_ust_abi_object_data *stream_data) @@ -1046,7 +1217,15 @@ int lttng_ust_ctl_send_stream_to_ust(int sock, stream_data->u.stream.wakeup_fd, 1); if (ret) return ret; - return ustcomm_recv_app_reply(sock, &lur, lum.handle, lum.cmd); + ret = ustcomm_recv_app_reply(sock, &lur, lum.handle, lum.cmd); + if (ret == -EINVAL) { + /* + * Command unknown from remote end. The communication socket is + * now out-of-sync and needs to be shutdown. + */ + (void) ustcomm_shutdown_unix_sock(sock); + } + return ret; } int lttng_ust_ctl_duplicate_ust_object_data(struct lttng_ust_abi_object_data **dest, @@ -1447,6 +1626,7 @@ struct lttng_ust_ctl_consumer_stream * struct lttng_ust_ring_buffer_channel *rb_chan; int shm_fd, wait_fd, wakeup_fd; uint64_t memory_map_size; + void *memory_map_addr; struct lttng_ust_ring_buffer *buf; int ret; @@ -1459,7 +1639,7 @@ struct lttng_ust_ctl_consumer_stream * buf = channel_get_ring_buffer(&rb_chan->backend.config, rb_chan, cpu, handle, &shm_fd, &wait_fd, - &wakeup_fd, &memory_map_size); + &wakeup_fd, &memory_map_size, &memory_map_addr); if (!buf) return NULL; ret = lib_ring_buffer_open_read(buf, handle); @@ -1475,6 +1655,7 @@ struct lttng_ust_ctl_consumer_stream * stream->wait_fd = wait_fd; stream->wakeup_fd = wakeup_fd; stream->memory_map_size = memory_map_size; + stream->memory_map_addr = memory_map_addr; stream->cpu = cpu; return stream; @@ -1542,12 +1723,21 @@ void *lttng_ust_ctl_get_mmap_base(struct lttng_ust_ctl_consumer_stream *stream) { struct lttng_ust_ring_buffer *buf; struct lttng_ust_ctl_consumer_channel *consumer_chan; + struct lttng_ust_sigbus_range range; + void *p; if (!stream) return NULL; buf = stream->buf; consumer_chan = stream->chan; - return shmp(consumer_chan->chan->priv->rb_chan->handle, buf->backend.memory_map); + if (sigbus_begin()) + return NULL; + lttng_ust_sigbus_add_range(&range, stream->memory_map_addr, + stream->memory_map_size); + p = shmp(consumer_chan->chan->priv->rb_chan->handle, buf->backend.memory_map); + lttng_ust_sigbus_del_range(&range); + sigbus_end(); + return p; /* Users of this pointer should check for sigbus. */ } /* returns the length to mmap. */ @@ -1603,6 +1793,8 @@ int lttng_ust_ctl_get_mmap_read_offset(struct lttng_ust_ctl_consumer_stream *str struct lttng_ust_ctl_consumer_channel *consumer_chan; struct lttng_ust_ring_buffer_backend_pages_shmp *barray_idx; struct lttng_ust_ring_buffer_backend_pages *pages; + struct lttng_ust_sigbus_range range; + int ret; if (!stream) return -EINVAL; @@ -1611,17 +1803,31 @@ int lttng_ust_ctl_get_mmap_read_offset(struct lttng_ust_ctl_consumer_stream *str rb_chan = consumer_chan->chan->priv->rb_chan; if (rb_chan->backend.config.output != RING_BUFFER_MMAP) return -EINVAL; + + if (sigbus_begin()) + return -EIO; + ret = 0; + lttng_ust_sigbus_add_range(&range, stream->memory_map_addr, + stream->memory_map_size); + sb_bindex = subbuffer_id_get_index(&rb_chan->backend.config, buf->backend.buf_rsb.id); barray_idx = shmp_index(rb_chan->handle, buf->backend.array, sb_bindex); - if (!barray_idx) - return -EINVAL; + if (!barray_idx) { + ret = -EINVAL; + goto end; + } pages = shmp(rb_chan->handle, barray_idx->shmp); - if (!pages) - return -EINVAL; + if (!pages) { + ret = -EINVAL; + goto end; + } *off = pages->mmap_offset; - return 0; +end: + lttng_ust_sigbus_del_range(&range); + sigbus_end(); + return ret; } /* returns the size of the current sub-buffer, without padding (for mmap). */ @@ -1631,6 +1837,7 @@ int lttng_ust_ctl_get_subbuf_size(struct lttng_ust_ctl_consumer_stream *stream, struct lttng_ust_ctl_consumer_channel *consumer_chan; struct lttng_ust_ring_buffer_channel *rb_chan; struct lttng_ust_ring_buffer *buf; + struct lttng_ust_sigbus_range range; if (!stream) return -EINVAL; @@ -1638,8 +1845,14 @@ int lttng_ust_ctl_get_subbuf_size(struct lttng_ust_ctl_consumer_stream *stream, buf = stream->buf; consumer_chan = stream->chan; rb_chan = consumer_chan->chan->priv->rb_chan; + if (sigbus_begin()) + return -EIO; + lttng_ust_sigbus_add_range(&range, stream->memory_map_addr, + stream->memory_map_size); *len = lib_ring_buffer_get_read_data_size(&rb_chan->backend.config, buf, rb_chan->handle); + lttng_ust_sigbus_del_range(&range); + sigbus_end(); return 0; } @@ -1650,15 +1863,22 @@ int lttng_ust_ctl_get_padded_subbuf_size(struct lttng_ust_ctl_consumer_stream *s struct lttng_ust_ctl_consumer_channel *consumer_chan; struct lttng_ust_ring_buffer_channel *rb_chan; struct lttng_ust_ring_buffer *buf; + struct lttng_ust_sigbus_range range; if (!stream) return -EINVAL; buf = stream->buf; consumer_chan = stream->chan; rb_chan = consumer_chan->chan->priv->rb_chan; + if (sigbus_begin()) + return -EIO; + lttng_ust_sigbus_add_range(&range, stream->memory_map_addr, + stream->memory_map_size); *len = lib_ring_buffer_get_read_data_size(&rb_chan->backend.config, buf, rb_chan->handle); *len = LTTNG_UST_PAGE_ALIGN(*len); + lttng_ust_sigbus_del_range(&range); + sigbus_end(); return 0; } @@ -1667,27 +1887,42 @@ int lttng_ust_ctl_get_next_subbuf(struct lttng_ust_ctl_consumer_stream *stream) { struct lttng_ust_ring_buffer *buf; struct lttng_ust_ctl_consumer_channel *consumer_chan; + struct lttng_ust_sigbus_range range; + int ret; if (!stream) return -EINVAL; buf = stream->buf; consumer_chan = stream->chan; - return lib_ring_buffer_get_next_subbuf(buf, + if (sigbus_begin()) + return -EIO; + lttng_ust_sigbus_add_range(&range, stream->memory_map_addr, + stream->memory_map_size); + ret = lib_ring_buffer_get_next_subbuf(buf, consumer_chan->chan->priv->rb_chan->handle); + lttng_ust_sigbus_del_range(&range); + sigbus_end(); + return ret; } - /* Release exclusive sub-buffer access, move consumer forward. */ int lttng_ust_ctl_put_next_subbuf(struct lttng_ust_ctl_consumer_stream *stream) { struct lttng_ust_ring_buffer *buf; struct lttng_ust_ctl_consumer_channel *consumer_chan; + struct lttng_ust_sigbus_range range; if (!stream) return -EINVAL; buf = stream->buf; consumer_chan = stream->chan; + if (sigbus_begin()) + return -EIO; + lttng_ust_sigbus_add_range(&range, stream->memory_map_addr, + stream->memory_map_size); lib_ring_buffer_put_next_subbuf(buf, consumer_chan->chan->priv->rb_chan->handle); + lttng_ust_sigbus_del_range(&range); + sigbus_end(); return 0; } @@ -1698,13 +1933,22 @@ int lttng_ust_ctl_snapshot(struct lttng_ust_ctl_consumer_stream *stream) { struct lttng_ust_ring_buffer *buf; struct lttng_ust_ctl_consumer_channel *consumer_chan; + struct lttng_ust_sigbus_range range; + int ret; if (!stream) return -EINVAL; buf = stream->buf; consumer_chan = stream->chan; - return lib_ring_buffer_snapshot(buf, &buf->cons_snapshot, + if (sigbus_begin()) + return -EIO; + lttng_ust_sigbus_add_range(&range, stream->memory_map_addr, + stream->memory_map_size); + ret = lib_ring_buffer_snapshot(buf, &buf->cons_snapshot, &buf->prod_snapshot, consumer_chan->chan->priv->rb_chan->handle); + lttng_ust_sigbus_del_range(&range); + sigbus_end(); + return ret; } /* @@ -1716,14 +1960,23 @@ int lttng_ust_ctl_snapshot_sample_positions(struct lttng_ust_ctl_consumer_stream { struct lttng_ust_ring_buffer *buf; struct lttng_ust_ctl_consumer_channel *consumer_chan; + struct lttng_ust_sigbus_range range; + int ret; if (!stream) return -EINVAL; buf = stream->buf; consumer_chan = stream->chan; - return lib_ring_buffer_snapshot_sample_positions(buf, + if (sigbus_begin()) + return -EIO; + lttng_ust_sigbus_add_range(&range, stream->memory_map_addr, + stream->memory_map_size); + ret = lib_ring_buffer_snapshot_sample_positions(buf, &buf->cons_snapshot, &buf->prod_snapshot, consumer_chan->chan->priv->rb_chan->handle); + lttng_ust_sigbus_del_range(&range); + sigbus_end(); + return ret; } /* Get the consumer position (iteration start) */ @@ -1758,13 +2011,22 @@ int lttng_ust_ctl_get_subbuf(struct lttng_ust_ctl_consumer_stream *stream, { struct lttng_ust_ring_buffer *buf; struct lttng_ust_ctl_consumer_channel *consumer_chan; + struct lttng_ust_sigbus_range range; + int ret; if (!stream) return -EINVAL; buf = stream->buf; consumer_chan = stream->chan; - return lib_ring_buffer_get_subbuf(buf, *pos, + if (sigbus_begin()) + return -EIO; + lttng_ust_sigbus_add_range(&range, stream->memory_map_addr, + stream->memory_map_size); + ret = lib_ring_buffer_get_subbuf(buf, *pos, consumer_chan->chan->priv->rb_chan->handle); + lttng_ust_sigbus_del_range(&range); + sigbus_end(); + return ret; } /* Release exclusive sub-buffer access */ @@ -1772,40 +2034,63 @@ int lttng_ust_ctl_put_subbuf(struct lttng_ust_ctl_consumer_stream *stream) { struct lttng_ust_ring_buffer *buf; struct lttng_ust_ctl_consumer_channel *consumer_chan; + struct lttng_ust_sigbus_range range; if (!stream) return -EINVAL; buf = stream->buf; consumer_chan = stream->chan; + if (sigbus_begin()) + return -EIO; + lttng_ust_sigbus_add_range(&range, stream->memory_map_addr, + stream->memory_map_size); lib_ring_buffer_put_subbuf(buf, consumer_chan->chan->priv->rb_chan->handle); + lttng_ust_sigbus_del_range(&range); + sigbus_end(); return 0; } -void lttng_ust_ctl_flush_buffer(struct lttng_ust_ctl_consumer_stream *stream, +int lttng_ust_ctl_flush_buffer(struct lttng_ust_ctl_consumer_stream *stream, int producer_active) { struct lttng_ust_ring_buffer *buf; struct lttng_ust_ctl_consumer_channel *consumer_chan; + struct lttng_ust_sigbus_range range; assert(stream); buf = stream->buf; consumer_chan = stream->chan; + if (sigbus_begin()) + return -EIO; + lttng_ust_sigbus_add_range(&range, stream->memory_map_addr, + stream->memory_map_size); lib_ring_buffer_switch_slow(buf, producer_active ? SWITCH_ACTIVE : SWITCH_FLUSH, consumer_chan->chan->priv->rb_chan->handle); + lttng_ust_sigbus_del_range(&range); + sigbus_end(); + return 0; } -void lttng_ust_ctl_clear_buffer(struct lttng_ust_ctl_consumer_stream *stream) +int lttng_ust_ctl_clear_buffer(struct lttng_ust_ctl_consumer_stream *stream) { struct lttng_ust_ring_buffer *buf; struct lttng_ust_ctl_consumer_channel *consumer_chan; + struct lttng_ust_sigbus_range range; assert(stream); buf = stream->buf; consumer_chan = stream->chan; + if (sigbus_begin()) + return -EIO; + lttng_ust_sigbus_add_range(&range, stream->memory_map_addr, + stream->memory_map_size); lib_ring_buffer_switch_slow(buf, SWITCH_ACTIVE, consumer_chan->chan->priv->rb_chan->handle); lib_ring_buffer_clear_reader(buf, consumer_chan->chan->priv->rb_chan->handle); + lttng_ust_sigbus_del_range(&range); + sigbus_end(); + return 0; } static @@ -1831,6 +2116,8 @@ int lttng_ust_ctl_get_timestamp_begin(struct lttng_ust_ctl_consumer_stream *stre struct lttng_ust_client_lib_ring_buffer_client_cb *client_cb; struct lttng_ust_ring_buffer_channel *chan; struct lttng_ust_ring_buffer *buf; + struct lttng_ust_sigbus_range range; + int ret; if (!stream || !timestamp_begin) return -EINVAL; @@ -1839,7 +2126,14 @@ int lttng_ust_ctl_get_timestamp_begin(struct lttng_ust_ctl_consumer_stream *stre client_cb = get_client_cb(buf, chan); if (!client_cb) return -ENOSYS; - return client_cb->timestamp_begin(buf, chan, timestamp_begin); + if (sigbus_begin()) + return -EIO; + lttng_ust_sigbus_add_range(&range, stream->memory_map_addr, + stream->memory_map_size); + ret = client_cb->timestamp_begin(buf, chan, timestamp_begin); + lttng_ust_sigbus_del_range(&range); + sigbus_end(); + return ret; } int lttng_ust_ctl_get_timestamp_end(struct lttng_ust_ctl_consumer_stream *stream, @@ -1848,6 +2142,8 @@ int lttng_ust_ctl_get_timestamp_end(struct lttng_ust_ctl_consumer_stream *stream struct lttng_ust_client_lib_ring_buffer_client_cb *client_cb; struct lttng_ust_ring_buffer_channel *chan; struct lttng_ust_ring_buffer *buf; + struct lttng_ust_sigbus_range range; + int ret; if (!stream || !timestamp_end) return -EINVAL; @@ -1856,7 +2152,14 @@ int lttng_ust_ctl_get_timestamp_end(struct lttng_ust_ctl_consumer_stream *stream client_cb = get_client_cb(buf, chan); if (!client_cb) return -ENOSYS; - return client_cb->timestamp_end(buf, chan, timestamp_end); + if (sigbus_begin()) + return -EIO; + lttng_ust_sigbus_add_range(&range, stream->memory_map_addr, + stream->memory_map_size); + ret = client_cb->timestamp_end(buf, chan, timestamp_end); + lttng_ust_sigbus_del_range(&range); + sigbus_end(); + return ret; } int lttng_ust_ctl_get_events_discarded(struct lttng_ust_ctl_consumer_stream *stream, @@ -1865,6 +2168,8 @@ int lttng_ust_ctl_get_events_discarded(struct lttng_ust_ctl_consumer_stream *str struct lttng_ust_client_lib_ring_buffer_client_cb *client_cb; struct lttng_ust_ring_buffer_channel *chan; struct lttng_ust_ring_buffer *buf; + struct lttng_ust_sigbus_range range; + int ret; if (!stream || !events_discarded) return -EINVAL; @@ -1873,7 +2178,14 @@ int lttng_ust_ctl_get_events_discarded(struct lttng_ust_ctl_consumer_stream *str client_cb = get_client_cb(buf, chan); if (!client_cb) return -ENOSYS; - return client_cb->events_discarded(buf, chan, events_discarded); + if (sigbus_begin()) + return -EIO; + lttng_ust_sigbus_add_range(&range, stream->memory_map_addr, + stream->memory_map_size); + ret = client_cb->events_discarded(buf, chan, events_discarded); + lttng_ust_sigbus_del_range(&range); + sigbus_end(); + return ret; } int lttng_ust_ctl_get_content_size(struct lttng_ust_ctl_consumer_stream *stream, @@ -1882,6 +2194,8 @@ int lttng_ust_ctl_get_content_size(struct lttng_ust_ctl_consumer_stream *stream, struct lttng_ust_client_lib_ring_buffer_client_cb *client_cb; struct lttng_ust_ring_buffer_channel *chan; struct lttng_ust_ring_buffer *buf; + struct lttng_ust_sigbus_range range; + int ret; if (!stream || !content_size) return -EINVAL; @@ -1890,7 +2204,14 @@ int lttng_ust_ctl_get_content_size(struct lttng_ust_ctl_consumer_stream *stream, client_cb = get_client_cb(buf, chan); if (!client_cb) return -ENOSYS; - return client_cb->content_size(buf, chan, content_size); + if (sigbus_begin()) + return -EIO; + lttng_ust_sigbus_add_range(&range, stream->memory_map_addr, + stream->memory_map_size); + ret = client_cb->content_size(buf, chan, content_size); + lttng_ust_sigbus_del_range(&range); + sigbus_end(); + return ret; } int lttng_ust_ctl_get_packet_size(struct lttng_ust_ctl_consumer_stream *stream, @@ -1899,6 +2220,8 @@ int lttng_ust_ctl_get_packet_size(struct lttng_ust_ctl_consumer_stream *stream, struct lttng_ust_client_lib_ring_buffer_client_cb *client_cb; struct lttng_ust_ring_buffer_channel *chan; struct lttng_ust_ring_buffer *buf; + struct lttng_ust_sigbus_range range; + int ret; if (!stream || !packet_size) return -EINVAL; @@ -1907,7 +2230,14 @@ int lttng_ust_ctl_get_packet_size(struct lttng_ust_ctl_consumer_stream *stream, client_cb = get_client_cb(buf, chan); if (!client_cb) return -ENOSYS; - return client_cb->packet_size(buf, chan, packet_size); + if (sigbus_begin()) + return -EIO; + lttng_ust_sigbus_add_range(&range, stream->memory_map_addr, + stream->memory_map_size); + ret = client_cb->packet_size(buf, chan, packet_size); + lttng_ust_sigbus_del_range(&range); + sigbus_end(); + return ret; } int lttng_ust_ctl_get_stream_id(struct lttng_ust_ctl_consumer_stream *stream, @@ -1916,6 +2246,8 @@ int lttng_ust_ctl_get_stream_id(struct lttng_ust_ctl_consumer_stream *stream, struct lttng_ust_client_lib_ring_buffer_client_cb *client_cb; struct lttng_ust_ring_buffer_channel *chan; struct lttng_ust_ring_buffer *buf; + struct lttng_ust_sigbus_range range; + int ret; if (!stream || !stream_id) return -EINVAL; @@ -1924,7 +2256,14 @@ int lttng_ust_ctl_get_stream_id(struct lttng_ust_ctl_consumer_stream *stream, client_cb = get_client_cb(buf, chan); if (!client_cb) return -ENOSYS; - return client_cb->stream_id(buf, chan, stream_id); + if (sigbus_begin()) + return -EIO; + lttng_ust_sigbus_add_range(&range, stream->memory_map_addr, + stream->memory_map_size); + ret = client_cb->stream_id(buf, chan, stream_id); + lttng_ust_sigbus_del_range(&range); + sigbus_end(); + return ret; } int lttng_ust_ctl_get_current_timestamp(struct lttng_ust_ctl_consumer_stream *stream, @@ -1933,6 +2272,8 @@ int lttng_ust_ctl_get_current_timestamp(struct lttng_ust_ctl_consumer_stream *st struct lttng_ust_client_lib_ring_buffer_client_cb *client_cb; struct lttng_ust_ring_buffer_channel *chan; struct lttng_ust_ring_buffer *buf; + struct lttng_ust_sigbus_range range; + int ret; if (!stream || !ts) return -EINVAL; @@ -1941,7 +2282,14 @@ int lttng_ust_ctl_get_current_timestamp(struct lttng_ust_ctl_consumer_stream *st client_cb = get_client_cb(buf, chan); if (!client_cb || !client_cb->current_timestamp) return -ENOSYS; - return client_cb->current_timestamp(buf, chan, ts); + if (sigbus_begin()) + return -EIO; + lttng_ust_sigbus_add_range(&range, stream->memory_map_addr, + stream->memory_map_size); + ret = client_cb->current_timestamp(buf, chan, ts); + lttng_ust_sigbus_del_range(&range); + sigbus_end(); + return ret; } int lttng_ust_ctl_get_sequence_number(struct lttng_ust_ctl_consumer_stream *stream, @@ -1950,6 +2298,8 @@ int lttng_ust_ctl_get_sequence_number(struct lttng_ust_ctl_consumer_stream *stre struct lttng_ust_client_lib_ring_buffer_client_cb *client_cb; struct lttng_ust_ring_buffer_channel *chan; struct lttng_ust_ring_buffer *buf; + struct lttng_ust_sigbus_range range; + int ret; if (!stream || !seq) return -EINVAL; @@ -1958,7 +2308,14 @@ int lttng_ust_ctl_get_sequence_number(struct lttng_ust_ctl_consumer_stream *stre client_cb = get_client_cb(buf, chan); if (!client_cb || !client_cb->sequence_number) return -ENOSYS; - return client_cb->sequence_number(buf, chan, seq); + if (sigbus_begin()) + return -EIO; + lttng_ust_sigbus_add_range(&range, stream->memory_map_addr, + stream->memory_map_size); + ret = client_cb->sequence_number(buf, chan, seq); + lttng_ust_sigbus_del_range(&range); + sigbus_end(); + return ret; } int lttng_ust_ctl_get_instance_id(struct lttng_ust_ctl_consumer_stream *stream, @@ -1967,6 +2324,8 @@ int lttng_ust_ctl_get_instance_id(struct lttng_ust_ctl_consumer_stream *stream, struct lttng_ust_client_lib_ring_buffer_client_cb *client_cb; struct lttng_ust_ring_buffer_channel *chan; struct lttng_ust_ring_buffer *buf; + struct lttng_ust_sigbus_range range; + int ret; if (!stream || !id) return -EINVAL; @@ -1975,7 +2334,14 @@ int lttng_ust_ctl_get_instance_id(struct lttng_ust_ctl_consumer_stream *stream, client_cb = get_client_cb(buf, chan); if (!client_cb) return -ENOSYS; - return client_cb->instance_id(buf, chan, id); + if (sigbus_begin()) + return -EIO; + lttng_ust_sigbus_add_range(&range, stream->memory_map_addr, + stream->memory_map_size); + ret = client_cb->instance_id(buf, chan, id); + lttng_ust_sigbus_del_range(&range); + sigbus_end(); + return ret; } #ifdef HAVE_LINUX_PERF_EVENT_H @@ -2763,6 +3129,14 @@ void lttng_ust_ctl_destroy_counter(struct lttng_ust_ctl_daemon_counter *counter) free(counter); } +/* + * Protocol for LTTNG_UST_ABI_COUNTER command: + * + * - send: struct ustcomm_ust_msg + * - receive: struct ustcomm_ust_reply + * - send: counter data + * - receive: struct ustcomm_ust_reply (actual command return code) + */ int lttng_ust_ctl_send_counter_data_to_ust(int sock, int parent_handle, struct lttng_ust_abi_object_data *counter_data) { @@ -2780,7 +3154,7 @@ int lttng_ust_ctl_send_counter_data_to_ust(int sock, int parent_handle, lum.handle = parent_handle; lum.cmd = LTTNG_UST_ABI_COUNTER; lum.u.counter.len = size; - ret = ustcomm_send_app_msg(sock, &lum); + ret = ustcomm_send_app_cmd(sock, &lum, &lur); if (ret) return ret; @@ -2800,6 +3174,14 @@ int lttng_ust_ctl_send_counter_data_to_ust(int sock, int parent_handle, return ret; } +/* + * Protocol for LTTNG_UST_ABI_COUNTER_GLOBAL command: + * + * - send: struct ustcomm_ust_msg + * - receive: struct ustcomm_ust_reply + * - send: file descriptor + * - receive: struct ustcomm_ust_reply (actual command return code) + */ int lttng_ust_ctl_send_counter_global_data_to_ust(int sock, struct lttng_ust_abi_object_data *counter_data, struct lttng_ust_abi_object_data *counter_global_data) @@ -2818,7 +3200,7 @@ int lttng_ust_ctl_send_counter_global_data_to_ust(int sock, lum.handle = counter_data->handle; /* parent handle */ lum.cmd = LTTNG_UST_ABI_COUNTER_GLOBAL; lum.u.counter_global.len = size; - ret = ustcomm_send_app_msg(sock, &lum); + ret = ustcomm_send_app_cmd(sock, &lum, &lur); if (ret) return ret; @@ -2838,6 +3220,14 @@ int lttng_ust_ctl_send_counter_global_data_to_ust(int sock, return ret; } +/* + * Protocol for LTTNG_UST_ABI_COUNTER_CPU command: + * + * - send: struct ustcomm_ust_msg + * - receive: struct ustcomm_ust_reply + * - send: file descriptor + * - receive: struct ustcomm_ust_reply (actual command return code) + */ int lttng_ust_ctl_send_counter_cpu_data_to_ust(int sock, struct lttng_ust_abi_object_data *counter_data, struct lttng_ust_abi_object_data *counter_cpu_data) @@ -2857,7 +3247,7 @@ int lttng_ust_ctl_send_counter_cpu_data_to_ust(int sock, lum.cmd = LTTNG_UST_ABI_COUNTER_CPU; lum.u.counter_cpu.len = size; lum.u.counter_cpu.cpu_nr = counter_cpu_data->u.counter_cpu.cpu_nr; - ret = ustcomm_send_app_msg(sock, &lum); + ret = ustcomm_send_app_cmd(sock, &lum, &lur); if (ret) return ret; @@ -2912,7 +3302,6 @@ void lttng_ust_ctl_ctor(void) */ lttng_ust_common_ctor(); - lttng_ust_clock_init(); lttng_ust_ring_buffer_clients_init(); lttng_ust_counter_clients_init(); lib_ringbuffer_signal_init();