Ejemplo n.º 1
0
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;
}
Ejemplo n.º 2
0
/* 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;
}