Version 2.2.3
[lttng-ust.git] / liblttng-ust-ctl / ustctl.c
index 641c508b8c979f20b651f255d8664bf2dafff3d2..c22f578536e873873a1b813efe8b311d39d74e29 100644 (file)
@@ -63,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;
@@ -596,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,
@@ -751,9 +756,7 @@ int ustctl_send_channel_to_ust(int sock, int session_handle,
                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;
 }
@@ -788,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 */
 
@@ -801,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;
                }
@@ -833,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:
@@ -848,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);
 }
@@ -928,19 +1059,27 @@ end:
 int ustctl_channel_close_wait_fd(struct ustctl_consumer_channel *consumer_chan)
 {
        struct channel *chan;
+       int ret;
 
        chan = consumer_chan->chan->chan;
-       return ring_buffer_channel_close_wait_fd(&chan->backend.config,
+       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;
-       return ring_buffer_channel_close_wakeup_fd(&chan->backend.config,
+       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)
@@ -1014,6 +1153,8 @@ 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);
 }
@@ -1441,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) {
@@ -1634,14 +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();
 }
This page took 0.034872 seconds and 4 git commands to generate.