static pthread_t kernel_thread;
static pthread_t dispatch_thread;
static pthread_t health_thread;
+static pthread_t ht_cleanup_thread;
/*
* UST registration command queue. This queue is tied with a futex and uses a N
*/
static int app_socket_timeout;
+/* Set in main() with the current page size. */
+long page_size;
+
static
void setup_consumerd_path(void)
{
/*
* This first step of the while is to clean this structure which could free
- * non NULL pointers so zero it before the loop.
+ * non NULL pointers so initialize it before the loop.
*/
- memset(&events, 0, sizeof(events));
+ lttng_poll_init(&events);
if (testpoint(thread_manage_kernel)) {
goto error_testpoint;
wait_node = zmalloc(sizeof(*wait_node));
if (!wait_node) {
PERROR("zmalloc wait_node dispatch");
+ ret = close(ust_cmd->sock);
+ if (ret < 0) {
+ PERROR("close ust sock dispatch %d", ust_cmd->sock);
+ }
+ lttng_fd_put(1, LTTNG_FD_APPS);
free(ust_cmd);
goto error;
}
break;
}
}
+
+ /*
+ * With no application at this stage the received socket is
+ * basically useless so close it before we free the cmd data
+ * structure for good.
+ */
+ if (!app) {
+ ret = close(ust_cmd->sock);
+ if (ret < 0) {
+ PERROR("close ust sock dispatch %d", ust_cmd->sock);
+ }
+ lttng_fd_put(1, LTTNG_FD_APPS);
+ }
free(ust_cmd);
}
rcu_read_unlock();
session_unlock_list();
- } else {
- /* Application manager threads are not available. */
- ret = close(ust_cmd->sock);
- if (ret < 0) {
- PERROR("close ust_cmd sock");
- }
- lttng_fd_put(1, LTTNG_FD_APPS);
}
} while (node != NULL);
* Copy consumer output from the tracing session to the domain session. The
* function also applies the right modification on a per domain basis for the
* trace files destination directory.
+ *
+ * Should *NOT* be called with RCU read-side lock held.
*/
static int copy_session_consumer(int domain, struct ltt_session *session)
{
/*
* Create an UST session and add it to the session ust list.
+ *
+ * Should *NOT* be called with RCU read-side lock held.
*/
static int create_ust_session(struct ltt_session *session,
struct lttng_domain *domain)
DBG("Creating UST session");
- lus = trace_ust_create_session(session->path, session->id);
+ lus = trace_ust_create_session(session->id);
if (lus == NULL) {
ret = LTTNG_ERR_UST_SESS_FAIL;
goto error;
* Return any error encountered or 0 for success.
*
* "sock" is only used for special-case var. len data.
+ *
+ * Should *NOT* be called with RCU read-side lock held.
*/
static int process_client_msg(struct command_ctx *cmd_ctx, int sock,
int *sock_error)
ret = setup_lttng_msg(cmd_ctx, nb_dom * sizeof(struct lttng_domain));
if (ret < 0) {
+ free(domains);
goto setup_error;
}
ret = setup_lttng_msg(cmd_ctx, nb_chan * sizeof(struct lttng_channel));
if (ret < 0) {
+ free(channels);
goto setup_error;
}
ret = setup_lttng_msg(cmd_ctx, nb_event * sizeof(struct lttng_event));
if (ret < 0) {
+ free(events);
goto setup_error;
}
rcu_register_thread();
+ /* We might hit an error path before this is created. */
+ lttng_poll_init(&events);
+
/* Create unix socket */
sock = lttcomm_create_unix_sock(health_unix_sock_path);
if (sock < 0) {
case LTTNG_HEALTH_CONSUMER:
reply.ret_code = check_consumer_health();
break;
+ case LTTNG_HEALTH_HT_CLEANUP:
+ reply.ret_code = health_check_state(HEALTH_TYPE_HT_CLEANUP);
+ break;
case LTTNG_HEALTH_ALL:
reply.ret_code =
health_check_state(HEALTH_TYPE_APP_MANAGE) &&
health_check_state(HEALTH_TYPE_APP_REG) &&
health_check_state(HEALTH_TYPE_CMD) &&
health_check_state(HEALTH_TYPE_KERNEL) &&
- check_consumer_health();
+ check_consumer_health() &&
+ health_check_state(HEALTH_TYPE_HT_CLEANUP);
break;
default:
reply.ret_code = LTTNG_ERR_UND;
PERROR("close");
}
}
- if (new_sock >= 0) {
- ret = close(new_sock);
- if (ret) {
- PERROR("close");
- }
- }
lttng_poll_clean(&events);
ret = process_client_msg(cmd_ctx, sock, &sock_error);
rcu_thread_offline();
if (ret < 0) {
- if (sock_error) {
- ret = close(sock);
- if (ret) {
- PERROR("close");
- }
- sock = -1;
+ ret = close(sock);
+ if (ret) {
+ PERROR("close");
}
+ sock = -1;
/*
* TODO: Inform client somehow of the fatal error. At
* this point, ret < 0 means that a zmalloc failed
setup_consumerd_path();
+ page_size = sysconf(_SC_PAGESIZE);
+ if (page_size < 0) {
+ PERROR("sysconf _SC_PAGESIZE");
+ page_size = LONG_MAX;
+ WARN("Fallback page size to %ld", page_size);
+ }
+
/* Parse arguments */
progname = argv[0];
if ((ret = parse_args(argc, argv)) < 0) {
}
}
+ /* Setup the thread ht_cleanup communication pipe. */
+ if (utils_create_pipe_cloexec(ht_cleanup_pipe) < 0) {
+ goto exit;
+ }
+
/* Setup the thread apps communication pipe. */
if ((ret = utils_create_pipe_cloexec(apps_cmd_pipe)) < 0) {
goto exit;
write_pidfile();
+ /* Create thread to manage the client socket */
+ ret = pthread_create(&ht_cleanup_thread, NULL,
+ thread_ht_cleanup, (void *) NULL);
+ if (ret != 0) {
+ PERROR("pthread_create ht_cleanup");
+ goto exit_ht_cleanup;
+ }
+
/* Create thread to manage the client socket */
ret = pthread_create(&health_thread, NULL,
thread_manage_health, (void *) NULL);
}
exit_health:
+ ret = pthread_join(ht_cleanup_thread, &status);
+ if (ret != 0) {
+ PERROR("pthread_join ht cleanup thread");
+ goto error; /* join error, exit without cleanup */
+ }
+exit_ht_cleanup:
exit:
/*
* cleanup() is called when no other thread is running.