ERR("Unable to clean %s", rundir);
}
free(cmd);
+ free(rundir);
DBG("Cleaning up all sessions");
DBG("[thread] Manage consumer started");
+ /*
+ * Since the consumer thread can be spawned at any moment in time, we init
+ * the health to a poll status (1, which is a valid health over time).
+ * When the thread starts, we update here the health to a "code" path being
+ * an even value so this thread, when reaching a poll wait, does not
+ * trigger an error with an even value.
+ *
+ * Here is the use case we avoid.
+ *
+ * +1: the first poll update during initialization (main())
+ * +2 * x: multiple code update once in this thread.
+ * +1: poll wait in this thread (being a good health state).
+ * == even number which after the wait period shows as a bad health.
+ *
+ * In a nutshell, the following poll update to the health state brings back
+ * the state to an even value meaning a code path.
+ */
+ health_poll_update(&consumer_data->health);
+
health_code_update(&consumer_data->health);
ret = lttcomm_listen_unix_sock(consumer_data->err_sock);
goto error;
}
+ /*
+ * Set the CLOEXEC flag. Return code is useless because either way, the
+ * show must go on.
+ */
+ (void) utils_set_fd_cloexec(sock);
+
health_code_update(&consumer_data->health);
DBG2("Receiving code from consumer err_sock");
ust_app_unregister(ust_cmd.sock);
} else {
/*
- * We just need here to monitor the close of the UST
- * socket and poll set monitor those by default.
- * Listen on POLLIN (even if we never expect any
- * data) to ensure that hangup wakes us.
+ * We only monitor the error events of the socket. This
+ * thread does not handle any incoming data from UST
+ * (POLLIN).
*/
- ret = lttng_poll_add(&events, ust_cmd.sock, LPOLLIN);
+ ret = lttng_poll_add(&events, ust_cmd.sock,
+ LPOLLERR & LPOLLHUP & LPOLLRDHUP);
if (ret < 0) {
goto error;
}
goto error;
}
+ /*
+ * Set the CLOEXEC flag. Return code is useless because
+ * either way, the show must go on.
+ */
+ (void) utils_set_fd_cloexec(sock);
+
/* Create UST registration command for enqueuing */
ust_cmd = zmalloc(sizeof(struct ust_command));
if (ust_cmd == NULL) {
case LTTNG_LIST_DOMAINS:
case LTTNG_START_TRACE:
case LTTNG_STOP_TRACE:
- case LTTNG_DATA_AVAILABLE:
+ case LTTNG_DATA_PENDING:
need_domain = 0;
break;
default:
ret = cmd_add_context(cmd_ctx->session, cmd_ctx->lsm->domain.type,
cmd_ctx->lsm->u.context.channel_name,
cmd_ctx->lsm->u.context.event_name,
- &cmd_ctx->lsm->u.context.ctx);
+ &cmd_ctx->lsm->u.context.ctx, kernel_poll_pipe[1]);
break;
}
case LTTNG_DISABLE_CHANNEL:
bytecode);
break;
}
- case LTTNG_DATA_AVAILABLE:
+ case LTTNG_DATA_PENDING:
{
- ret = cmd_data_available(cmd_ctx->session);
+ ret = cmd_data_pending(cmd_ctx->session);
break;
}
default:
goto error;
}
+ /*
+ * Set the CLOEXEC flag. Return code is useless because either way, the
+ * show must go on.
+ */
+ (void) utils_set_fd_cloexec(sock);
+
ret = lttcomm_listen_unix_sock(sock);
if (ret < 0) {
goto error;
goto error;
}
+ /*
+ * Set the CLOEXEC flag. Return code is useless because either way, the
+ * show must go on.
+ */
+ (void) utils_set_fd_cloexec(new_sock);
+
DBG("Receiving data from client for health...");
ret = lttcomm_recv_unix_sock(new_sock, (void *)&msg, sizeof(msg));
if (ret <= 0) {
goto error;
}
+ /*
+ * Set the CLOEXEC flag. Return code is useless because either way, the
+ * show must go on.
+ */
+ (void) utils_set_fd_cloexec(sock);
+
/* Set socket option for credentials retrieval */
ret = lttcomm_setsockopt_creds_unix_sock(sock);
if (ret < 0) {
goto end;
}
+ /* Set the cloexec flag */
+ ret = utils_set_fd_cloexec(client_sock);
+ if (ret < 0) {
+ ERR("Unable to set CLOEXEC flag to the client Unix socket (fd: %d). "
+ "Continuing but note that the consumer daemon will have a "
+ "reference to this socket on exec()", client_sock);
+ }
+
/* File permission MUST be 660 */
ret = chmod(client_unix_sock_path, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
if (ret < 0) {
goto end;
}
+ /* Set the cloexec flag */
+ ret = utils_set_fd_cloexec(apps_sock);
+ if (ret < 0) {
+ ERR("Unable to set CLOEXEC flag to the app Unix socket (fd: %d). "
+ "Continuing but note that the consumer daemon will have a "
+ "reference to this socket on exec()", apps_sock);
+ }
+
/* File permission MUST be 666 */
ret = chmod(apps_unix_sock_path,
S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
goto end;
}
+ DBG3("Session daemon client socket %d and application socket %d created",
+ client_sock, apps_sock);
+
end:
umask(old_umask);
return ret;
/*
* Init health counters of the consumer thread. We do a quick hack here to
* the state of the consumer health is fine even if the thread is not
- * started. This is simply to ease our life and has no cost what so ever.
+ * started. Once the thread starts, the health state is updated with a poll
+ * value to set a health code path. This is simply to ease our life and has
+ * no cost what so ever.
*/
health_init(&kconsumer_data.health);
health_poll_update(&kconsumer_data.health);
health_init(&ustconsumer64_data.health);
health_poll_update(&ustconsumer64_data.health);
- /* Not needed anymore. */
- free(rundir);
-
/* Create thread to manage the client socket */
ret = pthread_create(&health_thread, NULL,
thread_manage_health, (void *) NULL);