/* initial attributes */
struct ustctl_consumer_channel_attr attr;
+ int wait_fd; /* monitor close() */
+ int wakeup_fd; /* monitor close() */
};
/*
};
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;
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:
enum lttng_ust_chan_type type,
void *data,
uint64_t size,
+ int wakeup_fd,
int send_fd_only)
{
ssize_t len;
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;
}
{
struct lttng_ust_object_data *channel_data;
ssize_t len;
+ int wakeup_fd;
int ret;
channel_data = zmalloc(sizeof(*channel_data));
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,
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;
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;
}
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 */
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;
}
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:
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);
}
channel->attr.type,
table->objects[0].memory_map,
table->objects[0].memory_map_size,
+ channel->wakeup_fd,
0);
}
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);
}
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);
}
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;
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;
goto signature_error;
}
/* Enforce end of string */
- signature[signature_len - 1] = '\0';
+ a_sign[signature_len - 1] = '\0';
/* recv fields */
if (fields_len) {
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();
}