/* * 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; }
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; }