Fix shadow channel struct callback override in consumer
[lttng-ust.git] / liblttng-ust-ctl / ustctl.c
index 886e8485bc8cf683736b52b788d04e9cfdc0f1cf..b4234effc01212bb43f4150716429364a4f340e4 100644 (file)
@@ -22,6 +22,8 @@
 #include <lttng/ust-abi.h>
 #include <lttng/usterr-signal-safe.h>
 #include <lttng/ust-comm.h>
+#include <lttng/ust-events.h>
+#include <sys/mman.h>
 
 #include "../libringbuffer/backend.h"
 #include "../libringbuffer/frontend.h"
@@ -420,6 +422,8 @@ struct lttng_ust_shm_handle *ustctl_map_channel(struct lttng_ust_object_data *ch
        struct lttng_ust_shm_handle *handle;
        struct channel *chan;
        size_t chan_size;
+       struct lttng_ust_lib_ring_buffer_config *config;
+       int ret;
 
        handle = channel_handle_create(chan_data->shm_fd,
                chan_data->wait_fd,
@@ -449,6 +453,38 @@ struct lttng_ust_shm_handle *ustctl_map_channel(struct lttng_ust_object_data *ch
                return NULL;
        }
        memcpy(handle->shadow_chan, chan, chan_size);
+       /*
+        * The callback pointers in the producer are invalid in the
+        * consumer. We need to look them up here.
+        */
+       config = &handle->shadow_chan->backend.config;
+       switch (config->client_type) {
+       case LTTNG_CLIENT_METADATA:
+               memcpy(&config->cb, lttng_client_callbacks_metadata,
+                       sizeof(config->cb));
+               break;
+       case LTTNG_CLIENT_DISCARD:
+               memcpy(&config->cb, lttng_client_callbacks_discard,
+                       sizeof(config->cb));
+               break;
+       case LTTNG_CLIENT_OVERWRITE:
+               memcpy(&config->cb, lttng_client_callbacks_overwrite,
+                       sizeof(config->cb));
+               break;
+       default:
+               ERR("Unknown client type %d", config->client_type);
+               channel_destroy(chan, handle, 1);
+               return NULL;
+       }
+       /* Replace the object table pointer. */
+       ret = munmap(handle->table->objects[0].memory_map,
+               handle->table->objects[0].memory_map_size);
+       if (ret) {
+               perror("munmap");
+               assert(0);
+       }
+       handle->table->objects[0].memory_map = (char *) handle->shadow_chan;
+       handle->table->objects[0].is_shadow = 1;
        return handle;
 }
 
@@ -649,9 +685,11 @@ int ustctl_put_subbuf(struct lttng_ust_shm_handle *handle,
        return 0;
 }
 
-int ustctl_flush_buffer(struct lttng_ust_shm_handle *handle,
-               struct lttng_ust_lib_ring_buffer *buf)
+void ustctl_flush_buffer(struct lttng_ust_shm_handle *handle,
+               struct lttng_ust_lib_ring_buffer *buf,
+               int producer_active)
 {
-       lib_ring_buffer_switch_slow(buf, SWITCH_ACTIVE, handle);
-       return 0;
+       lib_ring_buffer_switch_slow(buf,
+               producer_active ? SWITCH_ACTIVE : SWITCH_FLUSH,
+               handle);
 }
This page took 0.025042 seconds and 4 git commands to generate.