Fix: close all file descriptors when executed as daemon
[lttng-tools.git] / src / bin / lttng-sessiond / main.c
index 7327c3cb2262ddf4337b46c08f2d02160f1136e7..5cfd57971f7423fe21f69c1d58b2cfafca99a05b 100644 (file)
@@ -33,7 +33,6 @@
 #include <sys/stat.h>
 #include <sys/types.h>
 #include <sys/wait.h>
 #include <sys/stat.h>
 #include <sys/types.h>
 #include <sys/wait.h>
-#include <urcu/futex.h>
 #include <urcu/uatomic.h>
 #include <unistd.h>
 #include <config.h>
 #include <urcu/uatomic.h>
 #include <unistd.h>
 #include <config.h>
 #include <common/defaults.h>
 #include <common/kernel-consumer/kernel-consumer.h>
 #include <common/ust-consumer/ust-consumer.h>
 #include <common/defaults.h>
 #include <common/kernel-consumer/kernel-consumer.h>
 #include <common/ust-consumer/ust-consumer.h>
+#include <common/futex.h>
 
 #include "lttng-sessiond.h"
 #include "channel.h"
 #include "context.h"
 #include "event.h"
 
 #include "lttng-sessiond.h"
 #include "channel.h"
 #include "context.h"
 #include "event.h"
-#include "futex.h"
 #include "kernel.h"
 #include "modprobe.h"
 #include "shm.h"
 #include "kernel.h"
 #include "modprobe.h"
 #include "shm.h"
@@ -2891,6 +2890,36 @@ error:
        return -ret;
 }
 
        return -ret;
 }
 
+/*
+ * Command LTTNG_LIST_TRACEPOINT_FIELDS processed by the client thread.
+ */
+static ssize_t cmd_list_tracepoint_fields(int domain,
+                       struct lttng_event_field **fields)
+{
+       int ret;
+       ssize_t nb_fields = 0;
+
+       switch (domain) {
+       case LTTNG_DOMAIN_UST:
+               nb_fields = ust_app_list_event_fields(fields);
+               if (nb_fields < 0) {
+                       ret = LTTCOMM_UST_LIST_FAIL;
+                       goto error;
+               }
+               break;
+       case LTTNG_DOMAIN_KERNEL:
+       default:        /* fall-through */
+               ret = LTTCOMM_UND;
+               goto error;
+       }
+
+       return nb_fields;
+
+error:
+       /* Return negative value to differentiate return code */
+       return -ret;
+}
+
 /*
  * Command LTTNG_START_TRACE processed by the client thread.
  */
 /*
  * Command LTTNG_START_TRACE processed by the client thread.
  */
@@ -3339,6 +3368,7 @@ static int process_client_msg(struct command_ctx *cmd_ctx)
        switch(cmd_ctx->lsm->cmd_type) {
        case LTTNG_LIST_SESSIONS:
        case LTTNG_LIST_TRACEPOINTS:
        switch(cmd_ctx->lsm->cmd_type) {
        case LTTNG_LIST_SESSIONS:
        case LTTNG_LIST_TRACEPOINTS:
+       case LTTNG_LIST_TRACEPOINT_FIELDS:
        case LTTNG_LIST_DOMAINS:
        case LTTNG_LIST_CHANNELS:
        case LTTNG_LIST_EVENTS:
        case LTTNG_LIST_DOMAINS:
        case LTTNG_LIST_CHANNELS:
        case LTTNG_LIST_EVENTS:
@@ -3358,6 +3388,7 @@ static int process_client_msg(struct command_ctx *cmd_ctx)
        case LTTNG_CALIBRATE:
        case LTTNG_LIST_SESSIONS:
        case LTTNG_LIST_TRACEPOINTS:
        case LTTNG_CALIBRATE:
        case LTTNG_LIST_SESSIONS:
        case LTTNG_LIST_TRACEPOINTS:
+       case LTTNG_LIST_TRACEPOINT_FIELDS:
                need_tracing_session = 0;
                break;
        default:
                need_tracing_session = 0;
                break;
        default:
@@ -3614,6 +3645,37 @@ skip_domain:
                ret = LTTCOMM_OK;
                break;
        }
                ret = LTTCOMM_OK;
                break;
        }
+       case LTTNG_LIST_TRACEPOINT_FIELDS:
+       {
+               struct lttng_event_field *fields;
+               ssize_t nb_fields;
+
+               nb_fields = cmd_list_tracepoint_fields(cmd_ctx->lsm->domain.type, &fields);
+               if (nb_fields < 0) {
+                       ret = -nb_fields;
+                       goto error;
+               }
+
+               /*
+                * Setup lttng message with payload size set to the event list size in
+                * bytes and then copy list into the llm payload.
+                */
+               ret = setup_lttng_msg(cmd_ctx, sizeof(struct lttng_event_field) * nb_fields);
+               if (ret < 0) {
+                       free(fields);
+                       goto setup_error;
+               }
+
+               /* Copy event list into message payload */
+               memcpy(cmd_ctx->llm->payload, fields,
+                               sizeof(struct lttng_event_field) * nb_fields);
+
+               free(fields);
+
+               ret = LTTCOMM_OK;
+               break;
+       }
+
        case LTTNG_START_TRACE:
        {
                ret = cmd_start_trace(cmd_ctx->session);
        case LTTNG_START_TRACE:
        {
                ret = cmd_start_trace(cmd_ctx->session);
@@ -3668,7 +3730,7 @@ skip_domain:
        }
        case LTTNG_LIST_CHANNELS:
        {
        }
        case LTTNG_LIST_CHANNELS:
        {
-               size_t nb_chan;
+               int nb_chan;
                struct lttng_channel *channels;
 
                nb_chan = cmd_list_channels(cmd_ctx->lsm->domain.type,
                struct lttng_channel *channels;
 
                nb_chan = cmd_list_channels(cmd_ctx->lsm->domain.type,
@@ -4198,13 +4260,15 @@ static int set_permissions(char *rundir)
        int ret;
        gid_t gid;
 
        int ret;
        gid_t gid;
 
-       gid = allowed_group();
-       if (gid < 0) {
+       ret = allowed_group();
+       if (ret < 0) {
                WARN("No tracing group detected");
                ret = 0;
                goto end;
        }
 
                WARN("No tracing group detected");
                ret = 0;
                goto end;
        }
 
+       gid = ret;
+
        /* Set lttng run dir */
        ret = chown(rundir, 0, gid);
        if (ret < 0) {
        /* Set lttng run dir */
        ret = chown(rundir, 0, gid);
        if (ret < 0) {
@@ -4483,11 +4547,6 @@ int main(int argc, char **argv)
 
        rcu_register_thread();
 
 
        rcu_register_thread();
 
-       /* Create thread quit pipe */
-       if ((ret = init_thread_quit_pipe()) < 0) {
-               goto error;
-       }
-
        setup_consumerd_path();
 
        /* Parse arguments */
        setup_consumerd_path();
 
        /* Parse arguments */
@@ -4498,11 +4557,31 @@ int main(int argc, char **argv)
 
        /* Daemonize */
        if (opt_daemon) {
 
        /* Daemonize */
        if (opt_daemon) {
+               int i;
+
+               /*
+                * fork
+                * child: setsid, close FD 0, 1, 2, chdir /
+                * parent: exit (if fork is successful)
+                */
                ret = daemon(0, 0);
                if (ret < 0) {
                        PERROR("daemon");
                        goto error;
                }
                ret = daemon(0, 0);
                if (ret < 0) {
                        PERROR("daemon");
                        goto error;
                }
+               /*
+                * We are in the child. Make sure all other file
+                * descriptors are closed, in case we are called with
+                * more opened file descriptors than the standard ones.
+                */
+               for (i = 3; i < sysconf(_SC_OPEN_MAX); i++) {
+                       (void) close(i);
+               }
+       }
+
+       /* Create thread quit pipe */
+       if ((ret = init_thread_quit_pipe()) < 0) {
+               goto error;
        }
 
        /* Check if daemon is UID = 0 */
        }
 
        /* Check if daemon is UID = 0 */
This page took 0.024745 seconds and 4 git commands to generate.