Beispiel #1
0
/*
 * Return -ENOENT if no more stream is available for creation.
 * Return 0 on success.
 * Return negative error value on error.
 */
int ustctl_create_stream(int sock, struct lttng_ust_object_data *channel_data,
		struct lttng_ust_object_data **_stream_data)
{
	struct ustcomm_ust_msg lum;
	struct ustcomm_ust_reply lur;
	struct lttng_ust_object_data *stream_data;
	int ret, fd, err = 0;

	if (!channel_data || !_stream_data)
		return -EINVAL;

	stream_data = malloc(sizeof(*stream_data));
	if (!stream_data)
		return -ENOMEM;
	init_object(stream_data);
	memset(&lum, 0, sizeof(lum));
	lum.handle = channel_data->handle;
	lum.cmd = LTTNG_UST_STREAM;
	ret = ustcomm_send_app_cmd(sock, &lum, &lur);
	if (ret) {
		free(stream_data);
		return ret;
	}
	if (lur.ret_code != USTCOMM_OK) {
		free(stream_data);
		return lur.ret_code;
	}

	stream_data->handle = lur.ret_val;
	DBG("received stream handle %u", stream_data->handle);
	stream_data->memory_map_size = lur.u.stream.memory_map_size;
	/* get shm fd */
	fd = ustcomm_recv_fd(sock);
	if (fd < 0)
		err = 1;
	else
		stream_data->shm_fd = fd;
	/*
	 * We need to get the second FD even if the first fails, because
	 * libust expects us to read the two FDs.
	 */
	/* get wait fd */
	fd = ustcomm_recv_fd(sock);
	if (fd < 0)
		err = 1;
	else
		stream_data->wait_fd = fd;
	if (err)
		goto error;
	*_stream_data = stream_data;
	return ret;

error:
	(void) ustctl_release_object(sock, stream_data);
	free(stream_data);
	return -EINVAL;
}
static
int open_streams(int sock, int channel_handle, struct lttng_ust_object_data *stream_datas,
		int nr_check)
{
	int ret, k = 0;

	for (;;) {
		struct ustcomm_ust_msg lum;
		struct ustcomm_ust_reply lur;

		memset(&lum, 0, sizeof(lum));
		lum.handle = channel_handle;
		lum.cmd = LTTNG_UST_STREAM;
		ret = ustcomm_send_app_cmd(sock, &lum, &lur);
		if (!ret) {
			assert(k < nr_check);
			stream_datas[k].handle = lur.ret_val;
			printf("received stream handle %u\n",
				stream_datas[k].handle);
			if (lur.ret_code == LTTNG_UST_OK) {
				ssize_t len;

				stream_datas[k].memory_map_size = lur.u.stream.memory_map_size;
				/* get shm fd */
				len = ustcomm_recv_fd(sock);
				if (len < 0)
					return -EINVAL;
				stream_datas[k].shm_fd = len;
				/* get wait fd */
				len = ustcomm_recv_fd(sock);
				if (len < 0)
					return -EINVAL;
				stream_datas[k].wait_fd = len;
			}
			k++;
		}
		if (ret == -LTTNG_UST_ERR_NOENT)
			break;
		if (ret)
			return ret;
	}
	return 0;
}
int send_app_msgs(int sock)
{
	struct ustcomm_ust_msg lum;
	struct ustcomm_ust_reply lur;
	int ret, i, j, k;

	for (i = 0; i < NR_SESSIONS; i++) {
		/* Create session */
		memset(&lum, 0, sizeof(lum));
		lum.handle = LTTNG_UST_ROOT_HANDLE;
		lum.cmd = LTTNG_UST_SESSION;
		ret = ustcomm_send_app_cmd(sock, &lum, &lur);
		if (ret)
			return ret;
		session_handle[i] = lur.ret_val;
		printf("received session handle %u\n", session_handle[i]);

		/* Create metadata channel */
		memset(&lum, 0, sizeof(lum));
		lum.handle = session_handle[i];
		lum.cmd = LTTNG_UST_METADATA;
		lum.u.channel.overwrite = 0;
		lum.u.channel.subbuf_size = 32768;
		lum.u.channel.num_subbuf = 4;
		lum.u.channel.switch_timer_interval = 0;
		lum.u.channel.read_timer_interval = 0;
		lum.u.channel.output = LTTNG_UST_MMAP;
		ret = ustcomm_send_app_cmd(sock, &lum, &lur);
		if (ret)
			return ret;
		metadata_data[i].handle = lur.ret_val;
		printf("received metadata handle %u\n", metadata_data[i].handle);
		if (lur.ret_code == LTTNG_UST_OK) {
			ssize_t len;

			metadata_data[i].memory_map_size = lur.u.channel.memory_map_size;
			/* get shm fd */
			len = ustcomm_recv_fd(sock);
			if (len < 0)
				return -EINVAL;
			metadata_data[i].shm_fd = len;
			/* get wait fd */
			len = ustcomm_recv_fd(sock);
			if (len < 0)
				return -EINVAL;
			metadata_data[i].wait_fd = len;
		}

		ret = open_streams(sock, metadata_data[i].handle,
				&metadata_stream_data[i], 1);
		if (ret) {
			printf("Error in open_streams\n");
			return ret;
		}

		/* Create channels */
		for (j = 0; j < NR_CHANNELS; j++) {
			memset(&lum, 0, sizeof(lum));
			lum.handle = session_handle[i];
			lum.cmd = LTTNG_UST_CHANNEL;
			//lum.u.channel.overwrite = 0;
			lum.u.channel.overwrite = 1;
			lum.u.channel.subbuf_size = 32768;
			lum.u.channel.num_subbuf = 8;
			//lum.u.channel.num_subbuf = 4;
			//lum.u.channel.num_subbuf = 2;
			lum.u.channel.switch_timer_interval = 0;
			lum.u.channel.read_timer_interval = 0;
			lum.u.channel.output = LTTNG_UST_MMAP;
			ret = ustcomm_send_app_cmd(sock, &lum, &lur);
			if (ret)
				return ret;
			channel_data[i][j].handle = lur.ret_val;
			printf("received channel handle %u\n", channel_data[i][j].handle);
			if (lur.ret_code == LTTNG_UST_OK) {
				ssize_t len;

				channel_data[i][j].memory_map_size = lur.u.channel.memory_map_size;
				/* get shm fd */
				len = ustcomm_recv_fd(sock);
				if (len < 0)
					return -EINVAL;
				channel_data[i][j].shm_fd = len;
				/* get wait fd */
				len = ustcomm_recv_fd(sock);
				if (len < 0)
					return -EINVAL;
				channel_data[i][j].wait_fd = len;
			}

			/* Create events */
			for (k = 0; k < NR_EVENTS; k++) {
				memset(&lum, 0, sizeof(lum));
				lum.handle = channel_data[i][j].handle;
				lum.cmd = LTTNG_UST_EVENT;
				strncpy(lum.u.event.name, evname[k],
					LTTNG_UST_SYM_NAME_LEN);
				lum.u.event.instrumentation = LTTNG_UST_TRACEPOINT;
				ret = ustcomm_send_app_cmd(sock, &lum, &lur);
				if (ret)
					return ret;
				event_handle[i][j][k] = lur.ret_val;
				printf("received event handle %u\n", event_handle[i][j][k]);
			}

			/* Get references to channel streams */
			ret = open_streams(sock, channel_data[i][j].handle,
					stream_data[i][j], MAX_NR_STREAMS);
			if (ret) {
				printf("Error in open_streams\n");
				return ret;
			}
		}

		memset(&lum, 0, sizeof(lum));
		lum.handle = session_handle[i];
		lum.cmd = LTTNG_UST_SESSION_START;
		ret = ustcomm_send_app_cmd(sock, &lum, &lur);
		if (ret)
			return ret;
		printf("Session handle %u started.\n", session_handle[i]);
	}

	/* Tell application registration is done */
	memset(&lum, 0, sizeof(lum));
	lum.handle = LTTNG_UST_ROOT_HANDLE;
	lum.cmd = LTTNG_UST_REGISTER_DONE;
	ret = ustcomm_send_app_cmd(sock, &lum, &lur);
	if (ret)
		return ret;
	printf("Registration done acknowledged.\n");

	sleep(4);

	ret = consume_buffers();
	if (ret) {
		printf("Error in consume_buffers\n");
		return ret;
	}

	for (i = 0; i < NR_SESSIONS; i++) {
		/* Release channels */
		for (j = 0; j < NR_CHANNELS; j++) {
			/* Release streams */
			ret = close_streams(sock, stream_data[i][j],
					MAX_NR_STREAMS);
			if (ret)
				return ret;

			/* Release events */
			for (k = 0; k < NR_EVENTS; k++) {
				memset(&lum, 0, sizeof(lum));
				lum.handle = event_handle[i][j][k];
				lum.cmd = LTTNG_UST_RELEASE;
				ret = ustcomm_send_app_cmd(sock, &lum, &lur);
				if (ret)
					return ret;
			}
			memset(&lum, 0, sizeof(lum));
			lum.handle = channel_data[i][j].handle;
			lum.cmd = LTTNG_UST_RELEASE;
			ret = ustcomm_send_app_cmd(sock, &lum, &lur);
			if (ret)
				return ret;
			if (channel_data[i][j].shm_fd >= 0) {
				ret = close(channel_data[i][j].shm_fd);
				if (ret)
					return ret;
			}
			if (channel_data[i][j].wait_fd >= 0) {
				ret = close(channel_data[i][j].wait_fd);
				if (ret)
					return ret;
			}
		}

		/* Release metadata channel */
		ret = close_streams(sock, &metadata_stream_data[i], 1);
		if (ret)
			return ret;

		memset(&lum, 0, sizeof(lum));
		lum.handle = metadata_data[i].handle;
		lum.cmd = LTTNG_UST_RELEASE;
		ret = ustcomm_send_app_cmd(sock, &lum, &lur);
		if (ret)
			return ret;
		if (metadata_data[i].shm_fd >= 0) {
			ret = close(metadata_data[i].shm_fd);
			if (ret)
				return ret;
		}
		if (metadata_data[i].wait_fd >= 0) {
			ret = close(metadata_data[i].wait_fd);
			if (ret)
				return ret;
		}

		/* Release session */
		memset(&lum, 0, sizeof(lum));
		lum.handle = session_handle[i];
		lum.cmd = LTTNG_UST_RELEASE;
		ret = ustcomm_send_app_cmd(sock, &lum, &lur);
		if (ret)
			return ret;
	}

	return 0;
}
Beispiel #4
0
int ustctl_create_channel(int sock, int session_handle,
		struct lttng_ust_channel_attr *chops,
		struct lttng_ust_object_data **_channel_data)
{
	struct ustcomm_ust_msg lum;
	struct ustcomm_ust_reply lur;
	struct lttng_ust_object_data *channel_data;
	int ret, err = 0;

	if (!chops || !_channel_data)
		return -EINVAL;

	channel_data = malloc(sizeof(*channel_data));
	if (!channel_data)
		return -ENOMEM;
	init_object(channel_data);
	/* Create metadata channel */
	memset(&lum, 0, sizeof(lum));
	lum.handle = session_handle;
	lum.cmd = LTTNG_UST_CHANNEL;
	lum.u.channel.overwrite = chops->overwrite;
	lum.u.channel.subbuf_size = chops->subbuf_size;
	lum.u.channel.num_subbuf = chops->num_subbuf;
	lum.u.channel.switch_timer_interval = chops->switch_timer_interval;
	lum.u.channel.read_timer_interval = chops->read_timer_interval;
	lum.u.channel.output = chops->output;
	ret = ustcomm_send_app_cmd(sock, &lum, &lur);
	if (ret) {
		free(channel_data);
		return ret;
	}
	if (lur.ret_code != USTCOMM_OK) {
		free(channel_data);
		return lur.ret_code;
	}
	channel_data->handle = lur.ret_val;
	DBG("received channel handle %u", channel_data->handle);
	channel_data->memory_map_size = lur.u.channel.memory_map_size;
	/* get shm fd */
	ret = ustcomm_recv_fd(sock);
	if (ret < 0)
		err = 1;
	else
		channel_data->shm_fd = ret;
	/*
	 * We need to get the second FD even if the first fails, because
	 * libust expects us to read the two FDs.
	 */
	/* get wait fd */
	ret = ustcomm_recv_fd(sock);
	if (ret < 0)
		err = 1;
	else
		channel_data->wait_fd = ret;
	if (err)
		goto error;
	*_channel_data = channel_data;
	return 0;

error:
	(void) ustctl_release_object(sock, channel_data);
	free(channel_data);
	return -EINVAL;
}