static struct lttng_ust_shm_handle *map_channel(struct lttng_ust_object_data *chan_data, struct lttng_ust_object_data *stream_datas, int nr_check) { struct lttng_ust_shm_handle *handle; struct channel *chan; int k, ret; /* map metadata channel */ handle = channel_handle_create(chan_data->shm_fd, chan_data->wait_fd, chan_data->memory_map_size); if (!handle) { printf("create handle error\n"); return NULL; } chan_data->shm_fd = -1; chan_data->wait_fd = -1; chan = shmp(handle, handle->chan); for (k = 0; k < nr_check; k++) { struct lttng_ust_object_data *stream_data = &stream_datas[k]; if (!stream_data->handle) break; /* map stream */ ret = channel_handle_add_stream(handle, stream_data->shm_fd, stream_data->wait_fd, stream_data->memory_map_size); if (ret) { printf("add stream error\n"); goto error_destroy; } stream_data->shm_fd = -1; stream_data->wait_fd = -1; } return handle; error_destroy: channel_destroy(chan, handle, 1); return NULL; }
/* Map channel shm into process memory */ struct lttng_ust_shm_handle *ustctl_map_channel(struct lttng_ust_object_data *chan_data) { struct lttng_ust_shm_handle *handle; struct channel *chan; size_t chan_size; struct lttng_ust_lib_ring_buffer_config *config; int ret; if (!chan_data) return NULL; handle = channel_handle_create(chan_data->shm_fd, chan_data->wait_fd, chan_data->memory_map_size); if (!handle) { ERR("create handle error"); return NULL; } /* * Set to -1, and then close the shm fd, and set the handle shm * fd to -1 too. We don't need the shm fds after they have been * mapped. * The wait_fd is set to -1 in chan_data because it is now owned * by the handle. */ chan_data->shm_fd = -1; chan_data->wait_fd = -1; /* chan is object 0. This is hardcoded. */ if (handle->table->objects[0].shm_fd >= 0) { ret = close(handle->table->objects[0].shm_fd); if (ret) { perror("Error closing shm_fd"); } handle->table->objects[0].shm_fd = -1; } /* * TODO: add consistency checks to be resilient if the * application try to feed us with incoherent channel structure * values. */ chan = shmp(handle, handle->chan); /* chan is object 0. This is hardcoded. */ chan_size = handle->table->objects[0].allocated_len; handle->shadow_chan = malloc(chan_size); if (!handle->shadow_chan) { channel_destroy(chan, handle, 1); 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; }