volatile enum ust_loglevel ust_loglevel;
+static int dummy_pipe[2];
+
+static
+void __attribute__((constructor)) setup_dummy_pipe(void)
+{
+ pipe(dummy_pipe);
+ /* Only dummy_pipe[0] is used */
+ close(dummy_pipe[1]);
+ /* FIXME: Handle pipe() failure */
+}
+
+static
+inline int get_dummy_fd(void)
+{
+ return dup(dummy_pipe[0]);
+}
+
static
void init_object(struct lttng_ust_object_data *data)
{
data->handle = -1;
data->shm_fd = -1;
+ data->shm_path = NULL;
data->wait_fd = -1;
+ data->wait_pipe_path = NULL;
data->memory_map_size = 0;
}
return ret;
}
}
+
+ if (data->shm_path) {
+ free(data->shm_path);
+ }
+
if (data->wait_fd >= 0) {
ret = close(data->wait_fd);
if (ret < 0) {
return ret;
}
}
+
+ if (data->wait_pipe_path) {
+ free(data->wait_pipe_path);
+ }
+
return ustctl_release_handle(sock, data->handle);
}
struct ustcomm_ust_reply lur;
struct lttng_ust_object_data *metadata_data;
int ret, err = 0;
+ char *shm_path, *wait_pipe_path;
if (!chops || !_metadata_data)
return -EINVAL;
metadata_data->handle = lur.ret_val;
DBG("received metadata handle %u", metadata_data->handle);
metadata_data->memory_map_size = lur.u.channel.memory_map_size;
- /* get shm fd */
- ret = ustcomm_recv_fd(sock);
- if (ret < 0)
+ /* get shm path */
+ shm_path = ustcomm_recv_string(sock);
+ if (!shm_path) {
err = 1;
- else
- metadata_data->shm_fd = ret;
+ } else {
+ DBG("Received shm path: %s\n", shm_path);
+ metadata_data->shm_fd = get_dummy_fd();
+ metadata_data->shm_path = shm_path;
+ }
+
/*
* 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)
+
+ /* get wait pipe path */
+ wait_pipe_path = ustcomm_recv_string(sock);
+ if (!wait_pipe_path) {
+ free(shm_path);
err = 1;
- else
- metadata_data->wait_fd = ret;
+ } else {
+ DBG("Received wait pipe path: %s\n", wait_pipe_path);
+ metadata_data->wait_fd = get_dummy_fd();
+ metadata_data->wait_pipe_path = wait_pipe_path;
+ }
+
+
if (err)
goto error;
*_metadata_data = metadata_data;
return -EINVAL;
}
+int ustctl_open_wait_pipe(int sock,
+ struct lttng_ust_object_data *channel_data)
+{
+ struct ustcomm_ust_msg lum;
+ struct ustcomm_ust_reply lur;
+ int ret;
+
+ if (!channel_data)
+ return -EINVAL;
+
+ /* Create metadata channel */
+ memset(&lum, 0, sizeof(lum));
+ lum.handle = channel_data->handle;
+ lum.cmd = LTTNG_UST_STREAM_PIPE;
+ ret = ustcomm_send_app_cmd(sock, &lum, &lur);
+
+ if (ret) {
+ goto error;
+ }
+ if (lur.ret_code != USTCOMM_OK) {
+ ret = lur.ret_code;
+ goto error;
+ }
+
+ return 0;
+
+error:
+ return ret;
+}
+
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_reply lur;
struct lttng_ust_object_data *channel_data;
int ret, err = 0;
+ char *shm_path, *wait_pipe_path;
if (!chops || !_channel_data)
return -EINVAL;
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)
+ /* get shm path */
+ shm_path = ustcomm_recv_string(sock);
+ if (!shm_path) {
err = 1;
- else
- channel_data->shm_fd = ret;
+ } else {
+ DBG("Received shm path: %s\n", shm_path);
+ channel_data->shm_fd = get_dummy_fd();
+ channel_data->shm_path = shm_path;
+ }
+
/*
* 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)
+ /* get wait pipe path */
+ wait_pipe_path = ustcomm_recv_string(sock);
+ if (!wait_pipe_path) {
+ free(shm_path);
err = 1;
- else
- channel_data->wait_fd = ret;
+ } else {
+ DBG("Received wait pipe path: %s\n", wait_pipe_path);
+ channel_data->wait_fd = get_dummy_fd();
+ channel_data->wait_pipe_path = wait_pipe_path;
+ }
+
if (err)
goto error;
*_channel_data = channel_data;
struct ustcomm_ust_msg lum;
struct ustcomm_ust_reply lur;
struct lttng_ust_object_data *stream_data;
- int ret, fd, err = 0;
+ int ret, err = 0;
+ char *shm_path, *wait_pipe_path;
if (!channel_data || !_stream_data)
return -EINVAL;
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)
+ /* get shm path */
+ shm_path = ustcomm_recv_string(sock);
+ if (!shm_path) {
err = 1;
- else
- stream_data->shm_fd = fd;
+ } else {
+ DBG("Received shm path: %s\n", shm_path);
+ stream_data->shm_fd = get_dummy_fd();
+ stream_data->shm_path = shm_path;
+ }
+
/*
* 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)
+ /* get wait pipe path */
+ wait_pipe_path = ustcomm_recv_string(sock);
+ if (!wait_pipe_path) {
+ free(shm_path);
err = 1;
- else
- stream_data->wait_fd = fd;
+ } else {
+ DBG("Received wait pipe path: %s\n", wait_pipe_path);
+ stream_data->wait_fd = get_dummy_fd();
+ stream_data->wait_pipe_path = wait_pipe_path;
+ }
+
if (err)
goto error;
*_stream_data = stream_data;
{
struct channel *chan;
int *shm_fd, *wait_fd;
+ char *shm_path, *wait_pipe_path;
uint64_t *memory_map_size;
struct lttng_ust_lib_ring_buffer *buf;
int ret;
chan = handle->shadow_chan;
buf = channel_get_ring_buffer(&chan->backend.config,
- chan, cpu, handle, &shm_fd, &wait_fd, &memory_map_size);
+ chan, cpu, handle,
+ &shm_fd, &shm_path,
+ &wait_fd, &wait_pipe_path,
+ &memory_map_size);
if (!buf)
return NULL;
ret = lib_ring_buffer_open_read(buf, handle, 1);