+ cmd_ctx->llm = NULL;
+ cmd_ctx->session = NULL;
+
+ health_code_update();
+
+ /*
+ * Data is received from the lttng client. The struct
+ * lttcomm_session_msg (lsm) contains the command and data request of
+ * the client.
+ */
+ DBG("Receiving data from client ...");
+ ret = lttcomm_recv_creds_unix_sock(sock, cmd_ctx->lsm,
+ sizeof(struct lttcomm_session_msg), &cmd_ctx->creds);
+ if (ret <= 0) {
+ DBG("Nothing recv() from client... continuing");
+ ret = close(sock);
+ if (ret) {
+ PERROR("close");
+ }
+ sock = -1;
+ clean_command_ctx(&cmd_ctx);
+ continue;
+ }
+
+ health_code_update();
+
+ // TODO: Validate cmd_ctx including sanity check for
+ // security purpose.
+
+ rcu_thread_online();
+ /*
+ * This function dispatch the work to the kernel or userspace tracer
+ * libs and fill the lttcomm_lttng_msg data structure of all the needed
+ * informations for the client. The command context struct contains
+ * everything this function may needs.
+ */
+ ret = process_client_msg(cmd_ctx, sock, &sock_error);
+ rcu_thread_offline();
+ if (ret < 0) {
+ 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
+ * (ENOMEM). Error detected but still accept
+ * command, unless a socket error has been
+ * detected.
+ */
+ clean_command_ctx(&cmd_ctx);
+ continue;
+ }
+
+ health_code_update();
+
+ DBG("Sending response (size: %d, retcode: %s (%d))",
+ cmd_ctx->lttng_msg_size,
+ lttng_strerror(-cmd_ctx->llm->ret_code),
+ cmd_ctx->llm->ret_code);
+ ret = send_unix_sock(sock, cmd_ctx->llm, cmd_ctx->lttng_msg_size);
+ if (ret < 0) {
+ ERR("Failed to send data back to client");
+ }
+
+ /* End of transmission */
+ ret = close(sock);
+ if (ret) {
+ PERROR("close");
+ }
+ sock = -1;
+
+ clean_command_ctx(&cmd_ctx);
+
+ health_code_update();
+ }
+
+exit:
+error:
+ if (sock >= 0) {
+ ret = close(sock);
+ if (ret) {
+ PERROR("close");
+ }
+ }
+
+ lttng_poll_clean(&events);
+ clean_command_ctx(&cmd_ctx);
+
+error_listen:
+error_create_poll:
+ unlink(client_unix_sock_path);
+ if (client_sock >= 0) {
+ ret = close(client_sock);
+ if (ret) {
+ PERROR("close");
+ }
+ }
+
+ if (err) {
+ health_error();
+ ERR("Health error occurred in %s", __func__);
+ }
+
+ health_unregister(health_sessiond);
+
+ DBG("Client thread dying");
+
+ rcu_unregister_thread();
+
+ /*
+ * Since we are creating the consumer threads, we own them, so we need
+ * to join them before our thread exits.
+ */
+ ret = join_consumer_thread(&kconsumer_data);
+ if (ret) {
+ errno = ret;
+ PERROR("join_consumer");
+ }
+
+ ret = join_consumer_thread(&ustconsumer32_data);
+ if (ret) {
+ errno = ret;
+ PERROR("join_consumer ust32");
+ }
+
+ ret = join_consumer_thread(&ustconsumer64_data);
+ if (ret) {
+ errno = ret;
+ PERROR("join_consumer ust64");
+ }
+ return NULL;
+}
+
+static int string_match(const char *str1, const char *str2)
+{
+ return (str1 && str2) && !strcmp(str1, str2);
+}
+
+/*
+ * Take an option from the getopt output and set it in the right variable to be
+ * used later.
+ *
+ * Return 0 on success else a negative value.
+ */
+static int set_option(int opt, const char *arg, const char *optname)
+{
+ int ret = 0;
+
+ if (string_match(optname, "client-sock") || opt == 'c') {
+ if (!arg || *arg == '\0') {
+ ret = -EINVAL;
+ goto end;
+ }
+ if (lttng_is_setuid_setgid()) {
+ WARN("Getting '%s' argument from setuid/setgid binary refused for security reasons.",
+ "-c, --client-sock");
+ } else {
+ snprintf(client_unix_sock_path, PATH_MAX, "%s", arg);
+ }
+ } else if (string_match(optname, "apps-sock") || opt == 'a') {
+ if (!arg || *arg == '\0') {
+ ret = -EINVAL;
+ goto end;
+ }
+ if (lttng_is_setuid_setgid()) {
+ WARN("Getting '%s' argument from setuid/setgid binary refused for security reasons.",
+ "-a, --apps-sock");
+ } else {
+ snprintf(apps_unix_sock_path, PATH_MAX, "%s", arg);
+ }
+ } else if (string_match(optname, "daemonize") || opt == 'd') {
+ opt_daemon = 1;
+ } else if (string_match(optname, "background") || opt == 'b') {
+ opt_background = 1;
+ } else if (string_match(optname, "group") || opt == 'g') {
+ if (!arg || *arg == '\0') {
+ ret = -EINVAL;
+ goto end;
+ }
+ if (lttng_is_setuid_setgid()) {
+ WARN("Getting '%s' argument from setuid/setgid binary refused for security reasons.",
+ "-g, --group");
+ } else {
+ /*
+ * If the override option is set, the pointer points to a
+ * *non* const thus freeing it even though the variable type is
+ * set to const.
+ */
+ if (tracing_group_name_override) {
+ free((void *) tracing_group_name);
+ }
+ tracing_group_name = strdup(arg);
+ if (!tracing_group_name) {
+ PERROR("strdup");
+ ret = -ENOMEM;
+ }
+ tracing_group_name_override = 1;
+ }
+ } else if (string_match(optname, "help") || opt == 'h') {
+ ret = utils_show_man_page(8, "lttng-sessiond");
+ if (ret) {
+ ERR("Cannot view man page lttng-sessiond(8)");
+ perror("exec");
+ }
+ exit(ret ? EXIT_FAILURE : EXIT_SUCCESS);
+ } else if (string_match(optname, "version") || opt == 'V') {
+ opt_print_version = 1;
+ } else if (string_match(optname, "sig-parent") || opt == 'S') {
+ opt_sig_parent = 1;
+ } else if (string_match(optname, "kconsumerd-err-sock")) {
+ if (!arg || *arg == '\0') {
+ ret = -EINVAL;
+ goto end;
+ }
+ if (lttng_is_setuid_setgid()) {
+ WARN("Getting '%s' argument from setuid/setgid binary refused for security reasons.",
+ "--kconsumerd-err-sock");
+ } else {
+ snprintf(kconsumer_data.err_unix_sock_path, PATH_MAX, "%s", arg);
+ }
+ } else if (string_match(optname, "kconsumerd-cmd-sock")) {
+ if (!arg || *arg == '\0') {
+ ret = -EINVAL;
+ goto end;
+ }
+ if (lttng_is_setuid_setgid()) {
+ WARN("Getting '%s' argument from setuid/setgid binary refused for security reasons.",
+ "--kconsumerd-cmd-sock");
+ } else {
+ snprintf(kconsumer_data.cmd_unix_sock_path, PATH_MAX, "%s", arg);
+ }
+ } else if (string_match(optname, "ustconsumerd64-err-sock")) {
+ if (!arg || *arg == '\0') {
+ ret = -EINVAL;
+ goto end;
+ }
+ if (lttng_is_setuid_setgid()) {
+ WARN("Getting '%s' argument from setuid/setgid binary refused for security reasons.",
+ "--ustconsumerd64-err-sock");
+ } else {
+ snprintf(ustconsumer64_data.err_unix_sock_path, PATH_MAX, "%s", arg);
+ }
+ } else if (string_match(optname, "ustconsumerd64-cmd-sock")) {
+ if (!arg || *arg == '\0') {
+ ret = -EINVAL;
+ goto end;
+ }
+ if (lttng_is_setuid_setgid()) {
+ WARN("Getting '%s' argument from setuid/setgid binary refused for security reasons.",
+ "--ustconsumerd64-cmd-sock");
+ } else {
+ snprintf(ustconsumer64_data.cmd_unix_sock_path, PATH_MAX, "%s", arg);
+ }
+ } else if (string_match(optname, "ustconsumerd32-err-sock")) {
+ if (!arg || *arg == '\0') {
+ ret = -EINVAL;
+ goto end;
+ }
+ if (lttng_is_setuid_setgid()) {
+ WARN("Getting '%s' argument from setuid/setgid binary refused for security reasons.",
+ "--ustconsumerd32-err-sock");
+ } else {
+ snprintf(ustconsumer32_data.err_unix_sock_path, PATH_MAX, "%s", arg);
+ }
+ } else if (string_match(optname, "ustconsumerd32-cmd-sock")) {
+ if (!arg || *arg == '\0') {
+ ret = -EINVAL;
+ goto end;
+ }
+ if (lttng_is_setuid_setgid()) {
+ WARN("Getting '%s' argument from setuid/setgid binary refused for security reasons.",
+ "--ustconsumerd32-cmd-sock");
+ } else {
+ snprintf(ustconsumer32_data.cmd_unix_sock_path, PATH_MAX, "%s", arg);
+ }
+ } else if (string_match(optname, "no-kernel")) {
+ opt_no_kernel = 1;
+ } else if (string_match(optname, "quiet") || opt == 'q') {
+ lttng_opt_quiet = 1;
+ } else if (string_match(optname, "verbose") || opt == 'v') {
+ /* Verbose level can increase using multiple -v */
+ if (arg) {
+ /* Value obtained from config file */
+ lttng_opt_verbose = config_parse_value(arg);
+ } else {
+ /* -v used on command line */
+ lttng_opt_verbose++;
+ }
+ /* Clamp value to [0, 3] */
+ lttng_opt_verbose = lttng_opt_verbose < 0 ? 0 :
+ (lttng_opt_verbose <= 3 ? lttng_opt_verbose : 3);
+ } else if (string_match(optname, "verbose-consumer")) {
+ if (arg) {
+ opt_verbose_consumer = config_parse_value(arg);
+ } else {
+ opt_verbose_consumer++;
+ }
+ } else if (string_match(optname, "consumerd32-path")) {
+ if (!arg || *arg == '\0') {
+ ret = -EINVAL;
+ goto end;
+ }
+ if (lttng_is_setuid_setgid()) {
+ WARN("Getting '%s' argument from setuid/setgid binary refused for security reasons.",
+ "--consumerd32-path");
+ } else {
+ if (consumerd32_bin_override) {
+ free((void *) consumerd32_bin);
+ }
+ consumerd32_bin = strdup(arg);
+ if (!consumerd32_bin) {
+ PERROR("strdup");
+ ret = -ENOMEM;
+ }
+ consumerd32_bin_override = 1;
+ }
+ } else if (string_match(optname, "consumerd32-libdir")) {
+ if (!arg || *arg == '\0') {
+ ret = -EINVAL;
+ goto end;
+ }
+ if (lttng_is_setuid_setgid()) {
+ WARN("Getting '%s' argument from setuid/setgid binary refused for security reasons.",
+ "--consumerd32-libdir");
+ } else {
+ if (consumerd32_libdir_override) {
+ free((void *) consumerd32_libdir);
+ }
+ consumerd32_libdir = strdup(arg);
+ if (!consumerd32_libdir) {
+ PERROR("strdup");
+ ret = -ENOMEM;
+ }
+ consumerd32_libdir_override = 1;
+ }
+ } else if (string_match(optname, "consumerd64-path")) {
+ if (!arg || *arg == '\0') {
+ ret = -EINVAL;
+ goto end;
+ }
+ if (lttng_is_setuid_setgid()) {
+ WARN("Getting '%s' argument from setuid/setgid binary refused for security reasons.",
+ "--consumerd64-path");
+ } else {
+ if (consumerd64_bin_override) {
+ free((void *) consumerd64_bin);
+ }
+ consumerd64_bin = strdup(arg);
+ if (!consumerd64_bin) {
+ PERROR("strdup");
+ ret = -ENOMEM;
+ }
+ consumerd64_bin_override = 1;
+ }
+ } else if (string_match(optname, "consumerd64-libdir")) {
+ if (!arg || *arg == '\0') {
+ ret = -EINVAL;
+ goto end;
+ }
+ if (lttng_is_setuid_setgid()) {
+ WARN("Getting '%s' argument from setuid/setgid binary refused for security reasons.",
+ "--consumerd64-libdir");
+ } else {
+ if (consumerd64_libdir_override) {
+ free((void *) consumerd64_libdir);
+ }
+ consumerd64_libdir = strdup(arg);
+ if (!consumerd64_libdir) {
+ PERROR("strdup");
+ ret = -ENOMEM;
+ }
+ consumerd64_libdir_override = 1;
+ }
+ } else if (string_match(optname, "pidfile") || opt == 'p') {
+ if (!arg || *arg == '\0') {
+ ret = -EINVAL;
+ goto end;
+ }
+ if (lttng_is_setuid_setgid()) {
+ WARN("Getting '%s' argument from setuid/setgid binary refused for security reasons.",
+ "-p, --pidfile");
+ } else {
+ free(opt_pidfile);
+ opt_pidfile = strdup(arg);
+ if (!opt_pidfile) {
+ PERROR("strdup");
+ ret = -ENOMEM;
+ }
+ }
+ } else if (string_match(optname, "agent-tcp-port")) {
+ if (!arg || *arg == '\0') {
+ ret = -EINVAL;
+ goto end;
+ }
+ if (lttng_is_setuid_setgid()) {
+ WARN("Getting '%s' argument from setuid/setgid binary refused for security reasons.",
+ "--agent-tcp-port");
+ } else {
+ unsigned long v;
+
+ errno = 0;
+ v = strtoul(arg, NULL, 0);
+ if (errno != 0 || !isdigit(arg[0])) {
+ ERR("Wrong value in --agent-tcp-port parameter: %s", arg);
+ return -1;