X-Git-Url: http://git.liburcu.org/?a=blobdiff_plain;f=liblttng-ust-ctl%2Fustctl.c;h=c22f578536e873873a1b813efe8b311d39d74e29;hb=1584cac2fb5dea4531f529b73a62eaccb95da897;hp=ff4a537b540b71e0b58a97fd24a029bfd8447af3;hpb=c9023c9304149ee1a4134571fdc41fd5e2e2a1a9;p=lttng-ust.git diff --git a/liblttng-ust-ctl/ustctl.c b/liblttng-ust-ctl/ustctl.c index ff4a537b..c22f5785 100644 --- a/liblttng-ust-ctl/ustctl.c +++ b/liblttng-ust-ctl/ustctl.c @@ -46,6 +46,8 @@ struct ustctl_consumer_channel { /* initial attributes */ struct ustctl_consumer_channel_attr attr; + int wait_fd; /* monitor close() */ + int wakeup_fd; /* monitor close() */ }; /* @@ -61,10 +63,14 @@ struct ustctl_consumer_stream { }; extern void lttng_ring_buffer_client_overwrite_init(void); +extern void lttng_ring_buffer_client_overwrite_rt_init(void); extern void lttng_ring_buffer_client_discard_init(void); +extern void lttng_ring_buffer_client_discard_rt_init(void); extern void lttng_ring_buffer_metadata_client_init(void); extern void lttng_ring_buffer_client_overwrite_exit(void); +extern void lttng_ring_buffer_client_overwrite_rt_exit(void); 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; @@ -95,6 +101,13 @@ int ustctl_release_object(int sock, struct lttng_ust_object_data *data) switch (data->type) { case LTTNG_UST_OBJECT_TYPE_CHANNEL: + if (data->u.channel.wakeup_fd >= 0) { + ret = close(data->u.channel.wakeup_fd); + if (ret < 0) { + ret = -errno; + return ret; + } + } free(data->u.channel.data); break; case LTTNG_UST_OBJECT_TYPE_STREAM: @@ -252,8 +265,6 @@ int ustctl_set_filter(int sock, struct lttng_ust_filter_bytecode *bytecode, ret = ustcomm_send_unix_sock(sock, bytecode->data, bytecode->len); if (ret < 0) { - if (ret == -ECONNRESET) - fprintf(stderr, "remote end closed connection\n"); return ret; } if (ret != bytecode->len) @@ -471,6 +482,7 @@ int ustctl_send_channel(int sock, enum lttng_ust_chan_type type, void *data, uint64_t size, + int wakeup_fd, int send_fd_only) { ssize_t len; @@ -504,6 +516,14 @@ int ustctl_send_channel(int sock, return -EIO; } + /* Send wakeup fd */ + len = ustcomm_send_fds_unix_sock(sock, &wakeup_fd, 1); + if (len <= 0) { + if (len < 0) + return len; + else + return -EIO; + } return 0; } @@ -571,6 +591,7 @@ int ustctl_recv_channel_from_consumer(int sock, { struct lttng_ust_object_data *channel_data; ssize_t len; + int wakeup_fd; int ret; channel_data = zmalloc(sizeof(*channel_data)); @@ -579,6 +600,7 @@ int ustctl_recv_channel_from_consumer(int sock, goto error_alloc; } channel_data->type = LTTNG_UST_OBJECT_TYPE_CHANNEL; + channel_data->handle = -1; /* recv mmap size */ len = ustcomm_recv_unix_sock(sock, &channel_data->size, @@ -617,7 +639,18 @@ int ustctl_recv_channel_from_consumer(int sock, ret = -EINVAL; goto error_recv_data; } - + /* recv wakeup fd */ + len = ustcomm_recv_fds_unix_sock(sock, &wakeup_fd, 1); + if (len <= 0) { + if (len < 0) { + ret = len; + goto error_recv_data; + } else { + ret = -EIO; + goto error_recv_data; + } + } + channel_data->u.channel.wakeup_fd = wakeup_fd; *_channel_data = channel_data; return 0; @@ -717,14 +750,13 @@ int ustctl_send_channel_to_ust(int sock, int session_handle, channel_data->u.channel.type, channel_data->u.channel.data, channel_data->size, + channel_data->u.channel.wakeup_fd, 1); if (ret) return ret; ret = ustcomm_recv_app_reply(sock, &lur, lum.handle, lum.cmd); if (!ret) { - if (lur.ret_val >= 0) { - channel_data->handle = lur.ret_val; - } + channel_data->handle = lur.ret_val; } return ret; } @@ -759,6 +791,119 @@ int ustctl_send_stream_to_ust(int sock, return ustcomm_recv_app_reply(sock, &lur, lum.handle, lum.cmd); } +int ustctl_duplicate_ust_object_data(struct lttng_ust_object_data **dest, + struct lttng_ust_object_data *src) +{ + struct lttng_ust_object_data *obj; + int ret; + + if (src->handle != -1) { + ret = -EINVAL; + goto error; + } + + obj = zmalloc(sizeof(*obj)); + if (!obj) { + ret = -ENOMEM; + goto error; + } + + obj->type = src->type; + obj->handle = src->handle; + obj->size = src->size; + + switch (obj->type) { + case LTTNG_UST_OBJECT_TYPE_CHANNEL: + { + obj->u.channel.type = src->u.channel.type; + if (src->u.channel.wakeup_fd >= 0) { + obj->u.channel.wakeup_fd = + dup(src->u.channel.wakeup_fd); + if (obj->u.channel.wakeup_fd < 0) { + ret = errno; + goto chan_error_wakeup_fd; + } + } else { + obj->u.channel.wakeup_fd = + src->u.channel.wakeup_fd; + } + obj->u.channel.data = zmalloc(obj->size); + if (!obj->u.channel.data) { + ret = -ENOMEM; + goto chan_error_alloc; + } + memcpy(obj->u.channel.data, src->u.channel.data, obj->size); + break; + + chan_error_alloc: + if (src->u.channel.wakeup_fd >= 0) { + int closeret; + + closeret = close(obj->u.channel.wakeup_fd); + if (closeret) { + PERROR("close"); + } + } + chan_error_wakeup_fd: + goto error_type; + + } + + case LTTNG_UST_OBJECT_TYPE_STREAM: + { + obj->u.stream.stream_nr = src->u.stream.stream_nr; + if (src->u.stream.wakeup_fd >= 0) { + obj->u.stream.wakeup_fd = + dup(src->u.stream.wakeup_fd); + if (obj->u.stream.wakeup_fd < 0) { + ret = errno; + goto stream_error_wakeup_fd; + } + } else { + obj->u.stream.wakeup_fd = + src->u.stream.wakeup_fd; + } + + if (src->u.stream.shm_fd >= 0) { + obj->u.stream.shm_fd = + dup(src->u.stream.shm_fd); + if (obj->u.stream.shm_fd < 0) { + ret = errno; + goto stream_error_shm_fd; + } + } else { + obj->u.stream.shm_fd = + src->u.stream.shm_fd; + } + break; + + stream_error_shm_fd: + if (src->u.stream.wakeup_fd >= 0) { + int closeret; + + closeret = close(obj->u.stream.wakeup_fd); + if (closeret) { + PERROR("close"); + } + } + stream_error_wakeup_fd: + goto error_type; + } + + default: + ret = -EINVAL; + goto error_type; + } + + *dest = obj; + return 0; + +error_type: + free(obj); +error: + return ret; +} + /* Buffer operations */ @@ -772,8 +917,19 @@ struct ustctl_consumer_channel * switch (attr->type) { case LTTNG_UST_CHAN_PER_CPU: if (attr->output == LTTNG_UST_MMAP) { - transport_name = attr->overwrite ? - "relay-overwrite-mmap" : "relay-discard-mmap"; + if (attr->overwrite) { + if (attr->read_timer_interval == 0) { + transport_name = "relay-overwrite-mmap"; + } else { + transport_name = "relay-overwrite-rt-mmap"; + } + } else { + if (attr->read_timer_interval == 0) { + transport_name = "relay-discard-mmap"; + } else { + transport_name = "relay-discard-rt-mmap"; + } + } } else { return NULL; } @@ -804,12 +960,14 @@ struct ustctl_consumer_channel * attr->subbuf_size, attr->num_subbuf, attr->switch_timer_interval, attr->read_timer_interval, - attr->uuid); + attr->uuid, attr->chan_id); if (!chan->chan) { goto chan_error; } chan->chan->ops = &transport->ops; memcpy(&chan->attr, attr, sizeof(chan->attr)); + chan->wait_fd = ustctl_channel_get_wait_fd(chan); + chan->wakeup_fd = ustctl_channel_get_wakeup_fd(chan); return chan; chan_error: @@ -819,6 +977,8 @@ chan_error: void ustctl_destroy_channel(struct ustctl_consumer_channel *chan) { + (void) ustctl_channel_close_wait_fd(chan); + (void) ustctl_channel_close_wakeup_fd(chan); chan->chan->ops->channel_destroy(chan->chan); free(chan); } @@ -835,6 +995,7 @@ int ustctl_send_channel_to_sessiond(int sock, channel->attr.type, table->objects[0].memory_map, table->objects[0].memory_map_size, + channel->wakeup_fd, 0); } @@ -895,12 +1056,38 @@ end: return ret; } +int ustctl_channel_close_wait_fd(struct ustctl_consumer_channel *consumer_chan) +{ + struct channel *chan; + int ret; + + chan = consumer_chan->chan->chan; + ret = ring_buffer_channel_close_wait_fd(&chan->backend.config, + chan, chan->handle); + if (!ret) + consumer_chan->wait_fd = -1; + return ret; +} + +int ustctl_channel_close_wakeup_fd(struct ustctl_consumer_channel *consumer_chan) +{ + struct channel *chan; + int ret; + + chan = consumer_chan->chan->chan; + ret = ring_buffer_channel_close_wakeup_fd(&chan->backend.config, + chan, chan->handle); + if (!ret) + consumer_chan->wakeup_fd = -1; + return ret; +} + int ustctl_stream_close_wait_fd(struct ustctl_consumer_stream *stream) { struct channel *chan; chan = stream->chan->chan->chan; - return ring_buffer_close_wait_fd(&chan->backend.config, + return ring_buffer_stream_close_wait_fd(&chan->backend.config, chan, stream->handle, stream->cpu); } @@ -909,7 +1096,7 @@ int ustctl_stream_close_wakeup_fd(struct ustctl_consumer_stream *stream) struct channel *chan; chan = stream->chan->chan->chan; - return ring_buffer_close_wakeup_fd(&chan->backend.config, + return ring_buffer_stream_close_wakeup_fd(&chan->backend.config, chan, stream->handle, stream->cpu); } @@ -966,11 +1153,29 @@ void ustctl_destroy_stream(struct ustctl_consumer_stream *stream) assert(stream); buf = stream->buf; consumer_chan = stream->chan; + (void) ustctl_stream_close_wait_fd(stream); + (void) ustctl_stream_close_wakeup_fd(stream); lib_ring_buffer_release_read(buf, consumer_chan->chan->handle); free(stream); } -int ustctl_get_wait_fd(struct ustctl_consumer_stream *stream) +int ustctl_channel_get_wait_fd(struct ustctl_consumer_channel *chan) +{ + if (!chan) + return -EINVAL; + return shm_get_wait_fd(chan->chan->handle, + &chan->chan->handle->chan._ref); +} + +int ustctl_channel_get_wakeup_fd(struct ustctl_consumer_channel *chan) +{ + if (!chan) + return -EINVAL; + return shm_get_wakeup_fd(chan->chan->handle, + &chan->chan->handle->chan._ref); +} + +int ustctl_stream_get_wait_fd(struct ustctl_consumer_stream *stream) { struct lttng_ust_lib_ring_buffer *buf; struct ustctl_consumer_channel *consumer_chan; @@ -982,7 +1187,7 @@ int ustctl_get_wait_fd(struct ustctl_consumer_stream *stream) return shm_get_wait_fd(consumer_chan->chan->handle, &buf->self._ref); } -int ustctl_get_wakeup_fd(struct ustctl_consumer_stream *stream) +int ustctl_stream_get_wakeup_fd(struct ustctl_consumer_stream *stream) { struct lttng_ust_lib_ring_buffer *buf; struct ustctl_consumer_channel *consumer_chan; @@ -1377,7 +1582,7 @@ int ustctl_recv_register_event(int sock, goto signature_error; } /* Enforce end of string */ - signature[signature_len - 1] = '\0'; + a_sign[signature_len - 1] = '\0'; /* recv fields */ if (fields_len) { @@ -1570,13 +1775,18 @@ void ustctl_init(void) init_usterr(); lttng_ring_buffer_metadata_client_init(); lttng_ring_buffer_client_overwrite_init(); + lttng_ring_buffer_client_overwrite_rt_init(); lttng_ring_buffer_client_discard_init(); + lttng_ring_buffer_client_discard_rt_init(); + lib_ringbuffer_signal_init(); } static __attribute__((destructor)) void ustctl_exit(void) { + lttng_ring_buffer_client_discard_rt_exit(); lttng_ring_buffer_client_discard_exit(); + lttng_ring_buffer_client_overwrite_rt_exit(); lttng_ring_buffer_client_overwrite_exit(); lttng_ring_buffer_metadata_client_exit(); }