int ustctl_create_event(int sock, struct lttng_ust_event *ev, struct lttng_ust_object_data *channel_data, struct lttng_ust_object_data **_event_data) { struct ustcomm_ust_msg lum; struct ustcomm_ust_reply lur; struct lttng_ust_object_data *event_data; int ret; if (!channel_data || !_event_data) return -EINVAL; event_data = malloc(sizeof(*event_data)); if (!event_data) return -ENOMEM; init_object(event_data); memset(&lum, 0, sizeof(lum)); lum.handle = channel_data->handle; lum.cmd = LTTNG_UST_EVENT; strncpy(lum.u.event.name, ev->name, LTTNG_UST_SYM_NAME_LEN); lum.u.event.instrumentation = ev->instrumentation; lum.u.event.loglevel_type = ev->loglevel_type; lum.u.event.loglevel = ev->loglevel; ret = ustcomm_send_app_cmd(sock, &lum, &lur); if (ret) { free(event_data); return ret; } event_data->handle = lur.ret_val; DBG("received event handle %u", event_data->handle); *_event_data = event_data; return 0; }
int ustctl_add_context(int sock, struct lttng_ust_context *ctx, struct lttng_ust_object_data *obj_data, struct lttng_ust_object_data **_context_data) { struct ustcomm_ust_msg lum; struct ustcomm_ust_reply lur; struct lttng_ust_object_data *context_data; int ret; if (!obj_data || !_context_data) return -EINVAL; context_data = malloc(sizeof(*context_data)); if (!context_data) return -ENOMEM; init_object(context_data); memset(&lum, 0, sizeof(lum)); lum.handle = obj_data->handle; lum.cmd = LTTNG_UST_CONTEXT; lum.u.context.ctx = ctx->ctx; ret = ustcomm_send_app_cmd(sock, &lum, &lur); if (ret) { free(context_data); return ret; } context_data->handle = lur.ret_val; DBG("received context handle %u", context_data->handle); *_context_data = context_data; return ret; }
int ustctl_tracepoint_field_list_get(int sock, int tp_field_list_handle, struct lttng_ust_field_iter *iter) { struct ustcomm_ust_msg lum; struct ustcomm_ust_reply lur; int ret; ssize_t len; if (!iter) return -EINVAL; memset(&lum, 0, sizeof(lum)); lum.handle = tp_field_list_handle; lum.cmd = LTTNG_UST_TRACEPOINT_FIELD_LIST_GET; ret = ustcomm_send_app_cmd(sock, &lum, &lur); if (ret) return ret; len = ustcomm_recv_unix_sock(sock, iter, sizeof(*iter)); if (len != sizeof(*iter)) { return -EINVAL; } DBG("received tracepoint field list entry event_name %s event_loglevel %d field_name %s field_type %d", iter->event_name, iter->loglevel, iter->field_name, iter->type); return 0; }
int ustctl_add_context(int sock, struct lttng_ust_context *ctx, struct lttng_ust_object_data *obj_data, struct lttng_ust_object_data **_context_data) { struct ustcomm_ust_msg lum; struct ustcomm_ust_reply lur; struct lttng_ust_object_data *context_data; int ret; if (!obj_data || !_context_data) return -EINVAL; context_data = zmalloc(sizeof(*context_data)); if (!context_data) return -ENOMEM; context_data->type = LTTNG_UST_OBJECT_TYPE_CONTEXT; memset(&lum, 0, sizeof(lum)); lum.handle = obj_data->handle; lum.cmd = LTTNG_UST_CONTEXT; lum.u.context = *ctx; ret = ustcomm_send_app_cmd(sock, &lum, &lur); if (ret) { free(context_data); return ret; } context_data->handle = -1; DBG("Context created successfully"); *_context_data = context_data; return ret; }
/* * 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; }
int ustctl_release_handle(int sock, int handle) { struct ustcomm_ust_msg lum; struct ustcomm_ust_reply lur; if (sock < 0 || handle < 0) return 0; memset(&lum, 0, sizeof(lum)); lum.handle = handle; lum.cmd = LTTNG_UST_RELEASE; return ustcomm_send_app_cmd(sock, &lum, &lur); }
int ustctl_wait_quiescent(int sock) { struct ustcomm_ust_msg lum; struct ustcomm_ust_reply lur; int ret; memset(&lum, 0, sizeof(lum)); lum.handle = LTTNG_UST_ROOT_HANDLE; lum.cmd = LTTNG_UST_WAIT_QUIESCENT; ret = ustcomm_send_app_cmd(sock, &lum, &lur); if (ret) return ret; DBG("waited for quiescent state"); return 0; }
/* * Send registration done packet to the application. */ int ustctl_register_done(int sock) { struct ustcomm_ust_msg lum; struct ustcomm_ust_reply lur; int ret; DBG("Sending register done command to %d", sock); 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; return 0; }
int ustctl_tracepoint_list(int sock) { struct ustcomm_ust_msg lum; struct ustcomm_ust_reply lur; int ret, tp_list_handle; memset(&lum, 0, sizeof(lum)); lum.handle = LTTNG_UST_ROOT_HANDLE; lum.cmd = LTTNG_UST_TRACEPOINT_LIST; ret = ustcomm_send_app_cmd(sock, &lum, &lur); if (ret) return ret; tp_list_handle = lur.ret_val; DBG("received tracepoint list handle %u", tp_list_handle); return tp_list_handle; }
/* * returns session handle. */ int ustctl_create_session(int sock) { struct ustcomm_ust_msg lum; struct ustcomm_ust_reply lur; int ret, session_handle; /* 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 = lur.ret_val; DBG("received session handle %u", session_handle); return session_handle; }
int ustctl_release_handle(int sock, int handle) { struct ustcomm_ust_msg lum; struct ustcomm_ust_reply lur; int ret; if (sock >= 0) { memset(&lum, 0, sizeof(lum)); lum.handle = handle; lum.cmd = LTTNG_UST_RELEASE; ret = ustcomm_send_app_cmd(sock, &lum, &lur); if (ret < 0) { return ret; } } return 0; }
int ustctl_sock_flush_buffer(int sock, struct lttng_ust_object_data *object) { struct ustcomm_ust_msg lum; struct ustcomm_ust_reply lur; int ret; if (!object) return -EINVAL; memset(&lum, 0, sizeof(lum)); lum.handle = object->handle; lum.cmd = LTTNG_UST_FLUSH_BUFFER; ret = ustcomm_send_app_cmd(sock, &lum, &lur); if (ret) return ret; DBG("flushed buffer handle %u", object->handle); return 0; }
/* Disable event, channel and session ioctl */ int ustctl_disable(int sock, struct lttng_ust_object_data *object) { struct ustcomm_ust_msg lum; struct ustcomm_ust_reply lur; int ret; if (!object) return -EINVAL; memset(&lum, 0, sizeof(lum)); lum.handle = object->handle; lum.cmd = LTTNG_UST_DISABLE; ret = ustcomm_send_app_cmd(sock, &lum, &lur); if (ret) return ret; DBG("disable handle %u", object->handle); return 0; }
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 ustctl_tracer_version(int sock, struct lttng_ust_tracer_version *v) { struct ustcomm_ust_msg lum; struct ustcomm_ust_reply lur; int ret; if (!v) return -EINVAL; memset(&lum, 0, sizeof(lum)); lum.handle = LTTNG_UST_ROOT_HANDLE; lum.cmd = LTTNG_UST_TRACER_VERSION; ret = ustcomm_send_app_cmd(sock, &lum, &lur); if (ret) return ret; memcpy(v, &lur.u.version, sizeof(*v)); DBG("received tracer version"); return 0; }
/* * Send registration done packet to the application. */ int ustctl_register_done(int sock) { struct ustcomm_ust_msg lum; struct ustcomm_ust_reply lur; int ret; DBG("Sending register done command to %d", sock); 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; if (lur.ret_code != USTCOMM_OK) { DBG("Return code: %s", ustcomm_get_readable_code(lur.ret_code)); goto error; } return 0; error: return -1; }
int ustctl_tracepoint_list_get(int sock, int tp_list_handle, struct lttng_ust_tracepoint_iter *iter) { struct ustcomm_ust_msg lum; struct ustcomm_ust_reply lur; int ret; if (!iter) return -EINVAL; memset(&lum, 0, sizeof(lum)); lum.handle = tp_list_handle; lum.cmd = LTTNG_UST_TRACEPOINT_LIST_GET; ret = ustcomm_send_app_cmd(sock, &lum, &lur); if (ret) return ret; DBG("received tracepoint list entry name %s loglevel %d", lur.u.tracepoint.name, lur.u.tracepoint.loglevel); memcpy(iter, &lur.u.tracepoint, sizeof(*iter)); return 0; }
static int close_streams(int sock, struct lttng_ust_object_data *stream_datas, int nr_check) { int ret, k; for (k = 0; k < nr_check; k++) { struct ustcomm_ust_msg lum; struct ustcomm_ust_reply lur; if (!stream_datas[k].handle) continue; memset(&lum, 0, sizeof(lum)); lum.handle = stream_datas[k].handle; lum.cmd = LTTNG_UST_RELEASE; ret = ustcomm_send_app_cmd(sock, &lum, &lur); if (ret) { printf("Error closing stream\n"); return ret; } if (stream_datas[k].shm_fd >= 0) { ret = close(stream_datas[k].shm_fd); if (ret) { printf("Error closing stream shm_fd\n"); return ret; } } if (stream_datas[k].wait_fd >= 0) { ret = close(stream_datas[k].wait_fd); if (ret) { printf("Error closing stream wait_fd\n"); 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; }