struct lttng_ht_iter iter;
struct ltt_ust_channel *uchan;
+ rcu_read_lock();
cds_lfht_for_each_entry(session->ust_session->domain_global.channels->ht,
&iter.iter, uchan, node.node) {
strncpy(channels[i].name, uchan->name, LTTNG_SYMBOL_NAME_LEN);
}
i++;
}
+ rcu_read_unlock();
break;
}
default:
assert(session);
+ rcu_read_lock();
+
if (session->consumer_fds_sent == 0 && session->consumer != NULL) {
cds_lfht_for_each_entry(session->consumer->socks->ht, &iter.iter,
socket, node.node) {
assert(socket->fd >= 0);
pthread_mutex_lock(socket->lock);
- ret = kernel_consumer_send_session(socket->fd, session);
+ ret = kernel_consumer_send_session(socket, session);
pthread_mutex_unlock(socket->lock);
if (ret < 0) {
ret = LTTNG_ERR_KERN_CONSUMER_FAIL;
}
error:
+ rcu_read_unlock();
return ret;
}
*/
static int send_consumer_relayd_socket(int domain, struct ltt_session *session,
struct lttng_uri *relayd_uri, struct consumer_output *consumer,
- int consumer_fd)
+ struct consumer_socket *consumer_sock)
{
int ret;
struct lttcomm_sock *sock = NULL;
}
/* Send relayd socket to consumer. */
- ret = consumer_send_relayd_socket(consumer_fd, sock,
- consumer, relayd_uri->stype);
+ ret = consumer_send_relayd_socket(consumer_sock, sock,
+ consumer, relayd_uri->stype, session->id);
if (ret < 0) {
ret = LTTNG_ERR_ENABLE_CONSUMER_FAIL;
goto close_sock;
* session.
*/
static int send_consumer_relayd_sockets(int domain,
- struct ltt_session *session, struct consumer_output *consumer, int fd)
+ struct ltt_session *session, struct consumer_output *consumer,
+ struct consumer_socket *sock)
{
int ret = LTTNG_OK;
/* Sending control relayd socket. */
if (!consumer->dst.net.control_sock_sent) {
ret = send_consumer_relayd_socket(domain, session,
- &consumer->dst.net.control, consumer, fd);
+ &consumer->dst.net.control, consumer, sock);
if (ret != LTTNG_OK) {
goto error;
}
/* Sending data relayd socket. */
if (!consumer->dst.net.data_sock_sent) {
ret = send_consumer_relayd_socket(domain, session,
- &consumer->dst.net.data, consumer, fd);
+ &consumer->dst.net.data, consumer, sock);
if (ret != LTTNG_OK) {
goto error;
}
DBG2("Setting relayd for session %s", session->name);
+ rcu_read_lock();
+
if (usess && usess->consumer && usess->consumer->type == CONSUMER_DST_NET
&& usess->consumer->enabled) {
/* For each consumer socket, send relayd sockets */
pthread_mutex_lock(socket->lock);
ret = send_consumer_relayd_sockets(LTTNG_DOMAIN_UST, session,
- usess->consumer, socket->fd);
+ usess->consumer, socket);
pthread_mutex_unlock(socket->lock);
if (ret != LTTNG_OK) {
goto error;
pthread_mutex_lock(socket->lock);
ret = send_consumer_relayd_sockets(LTTNG_DOMAIN_KERNEL, session,
- ksess->consumer, socket->fd);
+ ksess->consumer, socket);
pthread_mutex_unlock(socket->lock);
if (ret != LTTNG_OK) {
goto error;
}
error:
+ rcu_read_unlock();
return ret;
}
usess = session->ust_session;
+ rcu_read_lock();
+
switch (domain) {
case LTTNG_DOMAIN_KERNEL:
{
ret = LTTNG_OK;
error:
+ rcu_read_unlock();
return ret;
}
DBG("Enabling channel %s for session %s", attr->name, session->name);
+ rcu_read_lock();
+
switch (domain) {
case LTTNG_DOMAIN_KERNEL:
{
struct ltt_kernel_channel *kchan;
- /* Mandatory for a kernel channel. */
- assert(wpipe > 0);
-
kchan = trace_kernel_get_channel_by_name(attr->name,
session->kernel_session);
if (kchan == NULL) {
}
error:
+ rcu_read_unlock();
return ret;
}
{
int ret;
+ rcu_read_lock();
+
switch (domain) {
case LTTNG_DOMAIN_KERNEL:
{
goto error;
}
- ret = event_kernel_disable_tracepoint(ksess, kchan, event_name);
+ ret = event_kernel_disable_tracepoint(kchan, event_name);
if (ret != LTTNG_OK) {
goto error;
}
ret = LTTNG_OK;
error:
+ rcu_read_unlock();
return ret;
}
{
int ret;
+ rcu_read_lock();
+
switch (domain) {
case LTTNG_DOMAIN_KERNEL:
{
goto error;
}
- ret = event_kernel_disable_all(ksess, kchan);
+ ret = event_kernel_disable_all(kchan);
if (ret != LTTNG_OK) {
goto error;
}
ret = LTTNG_OK;
error:
+ rcu_read_unlock();
return ret;
}
* Command LTTNG_ADD_CONTEXT processed by the client thread.
*/
int cmd_add_context(struct ltt_session *session, int domain,
- char *channel_name, char *event_name, struct lttng_event_context *ctx,
- int kwpipe)
+ char *channel_name, struct lttng_event_context *ctx, int kwpipe)
{
int ret;
}
/* Add kernel context to kernel tracer */
- ret = context_kernel_add(session->kernel_session, ctx,
- event_name, channel_name);
+ ret = context_kernel_add(session->kernel_session, ctx, channel_name);
if (ret != LTTNG_OK) {
goto error;
}
free(attr);
}
-
- ret = context_ust_add(usess, domain, ctx, event_name, channel_name);
+ ret = context_ust_add(usess, domain, ctx, channel_name);
if (ret != LTTNG_OK) {
goto error;
}
return ret;
}
-/*
- * Command LTTNG_SET_FILTER processed by the client thread.
- */
-int cmd_set_filter(struct ltt_session *session, int domain,
- char *channel_name, char *event_name,
- struct lttng_filter_bytecode *bytecode)
-{
- int ret;
-
- switch (domain) {
- case LTTNG_DOMAIN_KERNEL:
- ret = LTTNG_ERR_FATAL;
- break;
- case LTTNG_DOMAIN_UST:
- {
- struct ltt_ust_session *usess = session->ust_session;
-
- ret = filter_ust_set(usess, domain, bytecode, event_name, channel_name);
- if (ret != LTTNG_OK) {
- goto error;
- }
- break;
- }
-#if 0
- case LTTNG_DOMAIN_UST_EXEC_NAME:
- case LTTNG_DOMAIN_UST_PID:
- case LTTNG_DOMAIN_UST_PID_FOLLOW_CHILDREN:
-#endif
- default:
- ret = LTTNG_ERR_UND;
- goto error;
- }
-
- ret = LTTNG_OK;
-
-error:
- return ret;
-
-}
-
-
/*
* Command LTTNG_ENABLE_EVENT processed by the client thread.
*/
int cmd_enable_event(struct ltt_session *session, int domain,
- char *channel_name, struct lttng_event *event, int wpipe)
+ char *channel_name, struct lttng_event *event,
+ struct lttng_filter_bytecode *filter, int wpipe)
{
- int ret;
+ int ret, channel_created = 0;
struct lttng_channel *attr;
assert(session);
assert(event);
assert(channel_name);
+ rcu_read_lock();
+
switch (domain) {
case LTTNG_DOMAIN_KERNEL:
{
goto error;
}
free(attr);
+
+ channel_created = 1;
}
/* Get the newly created kernel channel pointer */
goto error;
}
- ret = event_kernel_enable_tracepoint(session->kernel_session, kchan,
- event);
+ ret = event_kernel_enable_tracepoint(kchan, event);
if (ret != LTTNG_OK) {
+ if (channel_created) {
+ /* Let's not leak a useless channel. */
+ kernel_destroy_channel(kchan);
+ }
goto error;
}
}
/* At this point, the session and channel exist on the tracer */
- ret = event_ust_enable_tracepoint(usess, domain, uchan, event);
+ ret = event_ust_enable_tracepoint(usess, domain, uchan, event, filter);
if (ret != LTTNG_OK) {
goto error;
}
ret = LTTNG_OK;
error:
+ rcu_read_unlock();
return ret;
}
* Command LTTNG_ENABLE_ALL_EVENT processed by the client thread.
*/
int cmd_enable_event_all(struct ltt_session *session, int domain,
- char *channel_name, int event_type, int wpipe)
+ char *channel_name, int event_type,
+ struct lttng_filter_bytecode *filter, int wpipe)
{
int ret;
struct lttng_channel *attr;
assert(session);
assert(channel_name);
+ rcu_read_lock();
+
switch (domain) {
case LTTNG_DOMAIN_KERNEL:
{
switch (event_type) {
case LTTNG_EVENT_SYSCALL:
- ret = event_kernel_enable_all_syscalls(session->kernel_session,
- kchan, kernel_tracer_fd);
+ ret = event_kernel_enable_all_syscalls(kchan, kernel_tracer_fd);
break;
case LTTNG_EVENT_TRACEPOINT:
/*
* This call enables all LTTNG_KERNEL_TRACEPOINTS and
* events already registered to the channel.
*/
- ret = event_kernel_enable_all_tracepoints(session->kernel_session,
- kchan, kernel_tracer_fd);
+ ret = event_kernel_enable_all_tracepoints(kchan, kernel_tracer_fd);
break;
case LTTNG_EVENT_ALL:
/* Enable syscalls and tracepoints */
- ret = event_kernel_enable_all(session->kernel_session,
- kchan, kernel_tracer_fd);
+ ret = event_kernel_enable_all(kchan, kernel_tracer_fd);
break;
default:
ret = LTTNG_ERR_KERN_ENABLE_FAIL;
/* Manage return value */
if (ret != LTTNG_OK) {
+ /*
+ * On error, cmd_enable_channel call will take care of destroying
+ * the created channel if it was needed.
+ */
goto error;
}
switch (event_type) {
case LTTNG_EVENT_ALL:
case LTTNG_EVENT_TRACEPOINT:
- ret = event_ust_enable_all_tracepoints(usess, domain, uchan);
+ ret = event_ust_enable_all_tracepoints(usess, domain, uchan,
+ filter);
if (ret != LTTNG_OK) {
goto error;
}
ret = LTTNG_OK;
error:
+ rcu_read_unlock();
return ret;
}
pthread_mutex_lock(socket->lock);
ret = send_consumer_relayd_socket(domain, session, &uris[i],
- consumer, socket->fd);
+ consumer, socket);
pthread_mutex_unlock(socket->lock);
if (ret != LTTNG_OK) {
rcu_read_unlock();
socket = consumer_allocate_socket(sock);
if (socket == NULL) {
+ ret = close(sock);
+ if (ret < 0) {
+ PERROR("close register consumer");
+ }
ret = LTTNG_ERR_FATAL;
- close(sock);
goto error;
}