X-Git-Url: http://git.lttng.org./?a=blobdiff_plain;f=liblttng-ust-ctl%2Fustctl.c;h=744f66ba6dc9824c00329540d41c88294644bb2c;hb=04aa13f8c2944839f6514e3841b93057b443a783;hp=10fb9c4921f36ba4b4955fe90b892aeb9ce08e9b;hpb=53f0df512fb13a5c1b9609a001f9afd5114f2991;p=lttng-ust.git diff --git a/liblttng-ust-ctl/ustctl.c b/liblttng-ust-ctl/ustctl.c index 10fb9c49..744f66ba 100644 --- a/liblttng-ust-ctl/ustctl.c +++ b/liblttng-ust-ctl/ustctl.c @@ -16,14 +16,16 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#define _GNU_SOURCE +#include #include +#include +#include + +#include #include #include #include -#include -#include - +#include #include #include #include @@ -33,6 +35,7 @@ #include "../liblttng-ust/wait.h" #include "../liblttng-ust/lttng-rb-clients.h" #include "../liblttng-ust/clock.h" +#include "../liblttng-ust/getenv.h" /* * Number of milliseconds to retry before failing metadata writes on @@ -75,8 +78,6 @@ extern void lttng_ring_buffer_client_discard_exit(void); extern void lttng_ring_buffer_client_discard_rt_exit(void); extern void lttng_ring_buffer_metadata_client_exit(void); -volatile enum ust_loglevel ust_loglevel; - int ustctl_release_handle(int sock, int handle) { struct ustcomm_ust_msg lum; @@ -109,8 +110,10 @@ int ustctl_release_object(int sock, struct lttng_ust_object_data *data) ret = -errno; return ret; } + data->u.channel.wakeup_fd = -1; } free(data->u.channel.data); + data->u.channel.data = NULL; break; case LTTNG_UST_OBJECT_TYPE_STREAM: if (data->u.stream.shm_fd >= 0) { @@ -119,6 +122,7 @@ int ustctl_release_object(int sock, struct lttng_ust_object_data *data) ret = -errno; return ret; } + data->u.stream.shm_fd = -1; } if (data->u.stream.wakeup_fd >= 0) { ret = close(data->u.stream.wakeup_fd); @@ -126,10 +130,13 @@ int ustctl_release_object(int sock, struct lttng_ust_object_data *data) ret = -errno; return ret; } + data->u.stream.wakeup_fd = -1; } break; case LTTNG_UST_OBJECT_TYPE_EVENT: case LTTNG_UST_OBJECT_TYPE_CONTEXT: + case LTTNG_UST_OBJECT_TYPE_EVENT_NOTIFIER_GROUP: + case LTTNG_UST_OBJECT_TYPE_EVENT_NOTIFIER: break; default: assert(0); @@ -416,6 +423,97 @@ int ustctl_stop_session(int sock, int handle) return ustctl_disable(sock, &obj); } +int ustctl_create_event_notifier_group(int sock, int pipe_fd, + struct lttng_ust_object_data **_event_notifier_group_data) +{ + struct lttng_ust_object_data *event_notifier_group_data; + struct ustcomm_ust_msg lum; + struct ustcomm_ust_reply lur; + ssize_t len; + int ret; + + if (!_event_notifier_group_data) + return -EINVAL; + + event_notifier_group_data = zmalloc(sizeof(*event_notifier_group_data)); + if (!event_notifier_group_data) + return -ENOMEM; + + event_notifier_group_data->type = LTTNG_UST_OBJECT_TYPE_EVENT_NOTIFIER_GROUP; + + memset(&lum, 0, sizeof(lum)); + lum.handle = LTTNG_UST_ROOT_HANDLE; + lum.cmd = LTTNG_UST_EVENT_NOTIFIER_GROUP_CREATE; + + ret = ustcomm_send_app_msg(sock, &lum); + if (ret) + goto error; + + /* Send event_notifier notification pipe. */ + len = ustcomm_send_fds_unix_sock(sock, &pipe_fd, 1); + if (len <= 0) { + ret = len; + goto error; + } + + ret = ustcomm_recv_app_reply(sock, &lur, lum.handle, lum.cmd); + if (ret) + goto error; + + event_notifier_group_data->handle = lur.ret_val; + DBG("received event_notifier group handle %d", event_notifier_group_data->handle); + + *_event_notifier_group_data = event_notifier_group_data; + + ret = 0; + goto end; +error: + free(event_notifier_group_data); + +end: + return ret; +} + +int ustctl_create_event_notifier(int sock, struct lttng_ust_event_notifier *event_notifier, + struct lttng_ust_object_data *event_notifier_group, + struct lttng_ust_object_data **_event_notifier_data) +{ + struct ustcomm_ust_msg lum; + struct ustcomm_ust_reply lur; + struct lttng_ust_object_data *event_notifier_data; + int ret; + + if (!event_notifier_group || !_event_notifier_data) + return -EINVAL; + + event_notifier_data = zmalloc(sizeof(*event_notifier_data)); + if (!event_notifier_data) + return -ENOMEM; + + event_notifier_data->type = LTTNG_UST_OBJECT_TYPE_EVENT_NOTIFIER; + + memset(&lum, 0, sizeof(lum)); + lum.handle = event_notifier_group->handle; + lum.cmd = LTTNG_UST_EVENT_NOTIFIER_CREATE; + + strncpy(lum.u.event_notifier.event.name, event_notifier->event.name, + LTTNG_UST_SYM_NAME_LEN); + lum.u.event_notifier.event.instrumentation = event_notifier->event.instrumentation; + lum.u.event_notifier.event.loglevel_type = event_notifier->event.loglevel_type; + lum.u.event_notifier.event.loglevel = event_notifier->event.loglevel; + lum.u.event_notifier.event.token = event_notifier->event.token; + ret = ustcomm_send_app_cmd(sock, &lum, &lur); + if (ret) { + free(event_notifier_data); + return ret; + } + event_notifier_data->handle = lur.ret_val; + DBG("received event_notifier handle %u", event_notifier_data->handle); + *_event_notifier_data = event_notifier_data; + + return ret; +} + int ustctl_tracepoint_list(int sock) { struct ustcomm_ust_msg lum; @@ -1055,7 +1153,8 @@ struct ustctl_consumer_channel * attr->switch_timer_interval, attr->read_timer_interval, attr->uuid, attr->chan_id, - stream_fds, nr_stream_fds); + stream_fds, nr_stream_fds, + attr->blocking_timeout); if (!chan->chan) { goto chan_error; } @@ -1450,7 +1549,7 @@ int ustctl_get_padded_subbuf_size(struct ustctl_consumer_stream *stream, chan = consumer_chan->chan->chan; *len = lib_ring_buffer_get_read_data_size(&chan->backend.config, buf, consumer_chan->chan->handle); - *len = PAGE_ALIGN(*len); + *len = LTTNG_UST_PAGE_ALIGN(*len); return 0; } @@ -1499,6 +1598,25 @@ int ustctl_snapshot(struct ustctl_consumer_stream *stream) &buf->prod_snapshot, consumer_chan->chan->handle); } +/* + * Get a snapshot of the current ring buffer producer and consumer positions + * even if the consumed and produced positions are contained within the same + * subbuffer. + */ +int ustctl_snapshot_sample_positions(struct ustctl_consumer_stream *stream) +{ + struct lttng_ust_lib_ring_buffer *buf; + struct ustctl_consumer_channel *consumer_chan; + + if (!stream) + return -EINVAL; + buf = stream->buf; + consumer_chan = stream->chan; + return lib_ring_buffer_snapshot_sample_positions(buf, + &buf->cons_snapshot, &buf->prod_snapshot, + consumer_chan->chan->handle); +} + /* Get the consumer position (iteration start) */ int ustctl_snapshot_get_consumed(struct ustctl_consumer_stream *stream, unsigned long *pos) @@ -1568,6 +1686,19 @@ void ustctl_flush_buffer(struct ustctl_consumer_stream *stream, consumer_chan->chan->handle); } +void ustctl_clear_buffer(struct ustctl_consumer_stream *stream) +{ + struct lttng_ust_lib_ring_buffer *buf; + struct ustctl_consumer_channel *consumer_chan; + + assert(stream); + buf = stream->buf; + consumer_chan = stream->chan; + lib_ring_buffer_switch_slow(buf, SWITCH_ACTIVE, + consumer_chan->chan->handle); + lib_ring_buffer_clear_reader(buf, consumer_chan->chan->handle); +} + static struct lttng_ust_client_lib_ring_buffer_client_cb *get_client_cb( struct lttng_ust_lib_ring_buffer *buf, @@ -1708,7 +1839,41 @@ int ustctl_get_current_timestamp(struct ustctl_consumer_stream *stream, return client_cb->current_timestamp(buf, handle, ts); } -#if defined(__x86_64__) || defined(__i386__) +int ustctl_get_sequence_number(struct ustctl_consumer_stream *stream, + uint64_t *seq) +{ + struct lttng_ust_client_lib_ring_buffer_client_cb *client_cb; + struct lttng_ust_lib_ring_buffer *buf; + struct lttng_ust_shm_handle *handle; + + if (!stream || !seq) + return -EINVAL; + buf = stream->buf; + handle = stream->chan->chan->handle; + client_cb = get_client_cb(buf, handle); + if (!client_cb || !client_cb->sequence_number) + return -ENOSYS; + return client_cb->sequence_number(buf, handle, seq); +} + +int ustctl_get_instance_id(struct ustctl_consumer_stream *stream, + uint64_t *id) +{ + struct lttng_ust_client_lib_ring_buffer_client_cb *client_cb; + struct lttng_ust_lib_ring_buffer *buf; + struct lttng_ust_shm_handle *handle; + + if (!stream || !id) + return -EINVAL; + buf = stream->buf; + handle = stream->chan->chan->handle; + client_cb = get_client_cb(buf, handle); + if (!client_cb) + return -ENOSYS; + return client_cb->instance_id(buf, handle, id); +} + +#ifdef LTTNG_UST_HAVE_PERF_EVENT int ustctl_has_perf_counters(void) { @@ -1785,7 +1950,8 @@ int ustctl_recv_reg_msg(int sock, *uint64_t_alignment = reg_msg.uint64_t_alignment; *long_alignment = reg_msg.long_alignment; memcpy(name, reg_msg.name, LTTNG_UST_ABI_PROCNAME_LEN); - if (reg_msg.major != LTTNG_UST_ABI_MAJOR_VERSION) { + if (reg_msg.major < LTTNG_UST_ABI_MAJOR_VERSION_OLDEST_COMPATIBLE || + reg_msg.major > LTTNG_UST_ABI_MAJOR_VERSION) { return -LTTNG_UST_ERR_UNSUP_MAJOR; } @@ -2149,10 +2315,28 @@ int ustctl_reply_register_channel(int sock, return 0; } +/* Regenerate the statedump. */ +int ustctl_regenerate_statedump(int sock, int handle) +{ + struct ustcomm_ust_msg lum; + struct ustcomm_ust_reply lur; + int ret; + + memset(&lum, 0, sizeof(lum)); + lum.handle = handle; + lum.cmd = LTTNG_UST_SESSION_STATEDUMP; + ret = ustcomm_send_app_cmd(sock, &lum, &lur); + if (ret) + return ret; + DBG("Regenerated statedump for handle %u", handle); + return 0; +} + static __attribute__((constructor)) void ustctl_init(void) { init_usterr(); + lttng_ust_getenv_init(); /* Needs init_usterr() to be completed. */ lttng_ust_clock_init(); lttng_ring_buffer_metadata_client_init(); lttng_ring_buffer_client_overwrite_init();