struct health_state health_thread_app_reg;
struct health_state health_thread_kernel;
+/*
+ * Socket timeout for receiving and sending in seconds.
+ */
+static int app_socket_timeout;
+
static
void setup_consumerd_path(void)
{
*/
health_poll_update(&consumer_data->health);
- health_code_update(&consumer_data->health);
-
- ret = lttcomm_listen_unix_sock(consumer_data->err_sock);
- if (ret < 0) {
- goto error_listen;
- }
-
/*
* Pass 2 as size here for the thread quit pipe and kconsumerd_err_sock.
* Nothing more will be added to this poll set.
goto error_poll;
}
+ /*
+ * The error socket here is already in a listening state which was done
+ * just before spawning this thread to avoid a race between the consumer
+ * daemon exec trying to connect and the listen() call.
+ */
ret = lttng_poll_add(&events, consumer_data->err_sock, LPOLLIN | LPOLLRDHUP);
if (ret < 0) {
goto error;
lttng_poll_clean(&events);
error_poll:
-error_listen:
if (err) {
health_error(&consumer_data->health);
ERR("Health error occurred in %s", __func__);
goto error;
}
+ /* Set socket timeout for both receiving and ending */
+ (void) lttcomm_setsockopt_rcv_timeout(ust_cmd.sock,
+ app_socket_timeout);
+ (void) lttcomm_setsockopt_snd_timeout(ust_cmd.sock,
+ app_socket_timeout);
+
DBG("Apps with sock %d added to poll set",
ust_cmd.sock);
}
*/
static int start_consumerd(struct consumer_data *consumer_data)
{
- int ret;
+ int ret, err;
+
+ /*
+ * Set the listen() state on the socket since there is a possible race
+ * between the exec() of the consumer daemon and this call if place in the
+ * consumer thread. See bug #366 for more details.
+ */
+ ret = lttcomm_listen_unix_sock(consumer_data->err_sock);
+ if (ret < 0) {
+ goto error;
+ }
pthread_mutex_lock(&consumer_data->pid_mutex);
if (consumer_data->pid != 0) {
return 0;
error:
+ /* Cleanup already created socket on error. */
+ if (consumer_data->err_sock >= 0) {
+ err = close(consumer_data->err_sock);
+ if (err < 0) {
+ PERROR("close consumer data error socket");
+ }
+ }
return ret;
}
{
int ret = 0;
void *status;
- const char *home_path;
+ const char *home_path, *env_app_timeout;
init_kernel_workarounds();
health_init(&ustconsumer64_data.health);
health_poll_update(&ustconsumer64_data.health);
+ /* Check for the application socket timeout env variable. */
+ env_app_timeout = getenv(DEFAULT_APP_SOCKET_TIMEOUT_ENV);
+ if (env_app_timeout) {
+ app_socket_timeout = atoi(env_app_timeout);
+ } else {
+ app_socket_timeout = DEFAULT_APP_SOCKET_RW_TIMEOUT;
+ }
+
/* Create thread to manage the client socket */
ret = pthread_create(&health_thread, NULL,
thread_manage_health, (void *) NULL);