Fix a memory leak and "be nice" when handling stream alloc errors. Upon
CPU hotplug, it is possible that we receive a stream only after all
other streams are finalized, which means it could happen that we discard
that channel, in the unlikely event that we have cpu hotplug
concurrently with destroy.
Moreover, this fix the return path of channel lookup failure: we were
returning an zeroed stream rather than returning an error, which was
certainly not the intended behavior.
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Signed-off-by: David Goulet <dgoulet@efficios.com>
uid_t uid,
gid_t gid,
int net_index,
uid_t uid,
gid_t gid,
int net_index,
+ int metadata_flag,
+ int *alloc_ret)
{
struct lttng_consumer_stream *stream;
int ret;
{
struct lttng_consumer_stream *stream;
int ret;
stream = zmalloc(sizeof(*stream));
if (stream == NULL) {
perror("malloc struct lttng_consumer_stream");
stream = zmalloc(sizeof(*stream));
if (stream == NULL) {
perror("malloc struct lttng_consumer_stream");
+ *alloc_ret = -ENOMEM;
+ return NULL;
}
stream->chan = consumer_find_channel(channel_key);
if (!stream->chan) {
}
stream->chan = consumer_find_channel(channel_key);
if (!stream->chan) {
- perror("Unable to find channel key");
- goto end;
+ *alloc_ret = -ENOENT;
+ goto error;
}
stream->chan->refcount++;
stream->key = stream_key;
}
stream->chan->refcount++;
stream->key = stream_key;
stream->cpu = stream->chan->cpucount++;
ret = lttng_ustconsumer_allocate_stream(stream);
if (ret) {
stream->cpu = stream->chan->cpucount++;
ret = lttng_ustconsumer_allocate_stream(stream);
if (ret) {
- free(stream);
- return NULL;
+ *alloc_ret = -EINVAL;
+ goto error;
}
break;
default:
ERR("Unknown consumer_data type");
}
break;
default:
ERR("Unknown consumer_data type");
+ *alloc_ret = -EINVAL;
+ goto error;
stream->shm_fd, stream->wait_fd,
(unsigned long long) stream->mmap_len, stream->out_fd,
stream->net_seq_idx);
stream->shm_fd, stream->wait_fd,
(unsigned long long) stream->mmap_len, stream->out_fd,
stream->net_seq_idx);
+
+error:
+ free(stream);
+ return NULL;
uid_t uid,
gid_t gid,
int net_index,
uid_t uid,
gid_t gid,
int net_index,
+ int metadata_flag,
+ int *alloc_ret);
extern int consumer_add_stream(struct lttng_consumer_stream *stream);
extern void consumer_del_stream(struct lttng_consumer_stream *stream);
extern void consumer_change_stream_state(int stream_key,
extern int consumer_add_stream(struct lttng_consumer_stream *stream);
extern void consumer_del_stream(struct lttng_consumer_stream *stream);
extern void consumer_change_stream_state(int stream_key,
int fd;
struct consumer_relayd_sock_pair *relayd = NULL;
struct lttng_consumer_stream *new_stream;
int fd;
struct consumer_relayd_sock_pair *relayd = NULL;
struct lttng_consumer_stream *new_stream;
/* block */
if (lttng_consumer_poll_socket(consumer_sockpoll) < 0) {
/* block */
if (lttng_consumer_poll_socket(consumer_sockpoll) < 0) {
msg.u.stream.uid,
msg.u.stream.gid,
msg.u.stream.net_index,
msg.u.stream.uid,
msg.u.stream.gid,
msg.u.stream.net_index,
- msg.u.stream.metadata_flag);
+ msg.u.stream.metadata_flag,
+ &alloc_ret);
if (new_stream == NULL) {
if (new_stream == NULL) {
- lttng_consumer_send_error(ctx, LTTCOMM_CONSUMERD_OUTFD_ERROR);
+ switch (alloc_ret) {
+ case -ENOMEM:
+ case -EINVAL:
+ default:
+ lttng_consumer_send_error(ctx, LTTCOMM_CONSUMERD_OUTFD_ERROR);
+ break;
+ case -ENOENT:
+ /*
+ * We could not find the channel. Can happen if cpu hotplug
+ * happens while tearing down.
+ */
+ DBG3("Could not find channel");
+ break;
+ }
int fds[2];
size_t nb_fd = 2;
struct consumer_relayd_sock_pair *relayd = NULL;
int fds[2];
size_t nb_fd = 2;
struct consumer_relayd_sock_pair *relayd = NULL;
DBG("UST Consumer adding stream");
DBG("UST Consumer adding stream");
msg.u.stream.uid,
msg.u.stream.gid,
msg.u.stream.net_index,
msg.u.stream.uid,
msg.u.stream.gid,
msg.u.stream.net_index,
- msg.u.stream.metadata_flag);
+ msg.u.stream.metadata_flag,
+ &alloc_ret);
if (new_stream == NULL) {
if (new_stream == NULL) {
- lttng_consumer_send_error(ctx, LTTCOMM_CONSUMERD_OUTFD_ERROR);
+ switch (alloc_ret) {
+ case -ENOMEM:
+ case -EINVAL:
+ default:
+ lttng_consumer_send_error(ctx, LTTCOMM_CONSUMERD_OUTFD_ERROR);
+ break;
+ case -ENOENT:
+ /*
+ * We could not find the channel. Can happen if cpu hotplug
+ * happens while tearing down.
+ */
+ DBG3("Could not find channel");
+ break;
+ }