Merge branch 'master' into benchmark
authorDavid Goulet <dgoulet@efficios.com>
Fri, 20 Apr 2012 14:39:07 +0000 (10:39 -0400)
committerDavid Goulet <dgoulet@efficios.com>
Fri, 20 Apr 2012 14:39:07 +0000 (10:39 -0400)
Signed-off-by: David Goulet <dgoulet@efficios.com>
1  2 
configure.ac
src/bin/lttng-sessiond/main.c

diff --combined configure.ac
index 4a0d4e35220f3921b4e45af2b666721c21a524b8,5ff12a6d9ee13231cfea67f0a88dc88857e87b84..7ac225aa4d8ac5990aa7106aeb1ceb20fceb94c4
@@@ -1,4 -1,4 +1,4 @@@
- AC_INIT([lttng-tools],[2.0.0],[dgoulet@efficios.com],[],[http://lttng.org])
+ AC_INIT([lttng-tools],[2.0.1],[dgoulet@efficios.com],[],[http://lttng.org])
  AC_CONFIG_AUX_DIR([config])
  AC_CANONICAL_TARGET
  AC_CANONICAL_HOST
@@@ -81,11 -81,6 +81,11 @@@ AC_CHECK_LIB([popt], [poptGetContext], 
        [AC_MSG_ERROR([Cannot find libpopt. Use [LDFLAGS]=-Ldir to specify its location.])]
  )
  
 +# Needed for benchmark time
 +AC_CHECK_DECL([caa_get_cycles], [],
 +      [AC_MSG_ERROR([liburcu liburcu_version or newer is needed])], [[#include <urcu/arch.h>]]
 +)
 +
  # URCU library version needed or newer
  liburcu_version=">= 0.6.7"
  
@@@ -184,7 -179,6 +184,7 @@@ AC_CONFIG_FILES(
        doc/Makefile
        doc/man/Makefile
        include/Makefile
 +      benchmark/Makefile
        src/Makefile
        src/common/Makefile
        src/common/kernel-ctl/Makefile
        tests/ust/high-throughput/Makefile
        tests/ust/low-throughput/Makefile
        tests/ust/before-after/Makefile
+       tests/ust/multi-session/Makefile
  ])
  
  AC_OUTPUT
index e1783cd8e18b0ca00501d88122d633ac6bdb85ae,7327c3cb2262ddf4337b46c08f2d02160f1136e7..2d6111eb85d549c4572b885935ded22a78fff627
@@@ -34,6 -34,7 +34,7 @@@
  #include <sys/types.h>
  #include <sys/wait.h>
  #include <urcu/futex.h>
+ #include <urcu/uatomic.h>
  #include <unistd.h>
  #include <config.h>
  
@@@ -76,8 -77,6 +77,8 @@@ struct consumer_data 
        char cmd_unix_sock_path[PATH_MAX];
  };
  
 +#include "benchmark.h"
 +
  /* Const values */
  const char default_home_dir[] = DEFAULT_HOME_DIR;
  const char default_tracing_group[] = DEFAULT_TRACING_GROUP;
@@@ -181,6 -180,40 +182,40 @@@ static const char *consumerd64_bin = CO
  static const char *consumerd32_libdir = CONFIG_CONSUMERD32_LIBDIR;
  static const char *consumerd64_libdir = CONFIG_CONSUMERD64_LIBDIR;
  
+ /*
+  * Consumer daemon state which is changed when spawning it, killing it or in
+  * case of a fatal error.
+  */
+ enum consumerd_state {
+       CONSUMER_STARTED = 1,
+       CONSUMER_STOPPED = 2,
+       CONSUMER_ERROR   = 3,
+ };
+ /*
+  * This consumer daemon state is used to validate if a client command will be
+  * able to reach the consumer. If not, the client is informed. For instance,
+  * doing a "lttng start" when the consumer state is set to ERROR will return an
+  * error to the client.
+  *
+  * The following example shows a possible race condition of this scheme:
+  *
+  * consumer thread error happens
+  *                                    client cmd arrives
+  *                                    client cmd checks state -> still OK
+  * consumer thread exit, sets error
+  *                                    client cmd try to talk to consumer
+  *                                    ...
+  *
+  * However, since the consumer is a different daemon, we have no way of making
+  * sure the command will reach it safely even with this state flag. This is why
+  * we consider that up to the state validation during command processing, the
+  * command is safe. After that, we can not guarantee the correctness of the
+  * client request vis-a-vis the consumer.
+  */
+ static enum consumerd_state ust_consumerd_state;
+ static enum consumerd_state kernel_consumerd_state;
  static
  void setup_consumerd_path(void)
  {
@@@ -452,7 -485,6 +487,6 @@@ static void cleanup(void
                        if (ret) {
                                PERROR("close");
                        }
                }
        }
        for (i = 0; i < 2; i++) {
                }
        }
  
 +      /* OUTPUT BENCHMARK RESULTS */
 +      //bench_init();
 +
 +      if (getenv("BENCH_UST_NOTIFY")) {
 +              bench_print_ust_notification();
 +      }
 +
 +      if (getenv("BENCH_UST_REGISTER")) {
 +              bench_print_ust_register();
 +              bench_print_ust_unregister();
 +      }
 +
 +      if (getenv("BENCH_BOOT_PROCESS")) {
 +              bench_print_boot_process();
 +      }
 +
 +      if (getenv("BENCH_COMMANDS")) {
 +              bench_print_enable_ust_event();
 +      }
 +
 +      bench_close();
 +      /* END BENCHMARK */
 +
        /* <fun> */
        DBG("%c[%d;%dm*** assert failed :-) *** ==> %c[%dm%c[%d;%dm"
                        "Matthew, BEET driven development works!%c[%dm",
@@@ -683,13 -692,9 +717,13 @@@ static int notify_ust_apps(int active
                goto error;
        }
  
 +      tracepoint(ust_notify_apps_start);
 +
        /* Wake waiting process */
        futex_wait_update((int32_t *) wait_shm_mmap, active);
  
 +      tracepoint(ust_notify_apps_stop);
 +
        /* Apps notified successfully */
        return 0;
  
@@@ -868,8 -873,6 +902,8 @@@ static void *thread_manage_kernel(void 
        char tmp;
        struct lttng_poll_event events;
  
 +      tracepoint(sessiond_th_kern_start);
 +
        DBG("Thread manage kernel started");
  
        ret = create_thread_poll_set(&events, 2);
                /* Zeroed the poll events */
                lttng_poll_reset(&events);
  
 +              tracepoint(sessiond_th_kern_poll);
 +
                /* Poll infinite value of time */
        restart:
                ret = lttng_poll_wait(&events, -1);
@@@ -978,8 -979,6 +1012,8 @@@ static void *thread_manage_consumer(voi
        struct lttng_poll_event events;
        struct consumer_data *consumer_data = data;
  
 +      tracepoint(sessiond_th_kcon_start);
 +
        DBG("[thread] Manage consumer started");
  
        ret = lttcomm_listen_unix_sock(consumer_data->err_sock);
  
        nb_fd = LTTNG_POLL_GETNB(&events);
  
 +      tracepoint(sessiond_th_kcon_poll);
 +
        /* Inifinite blocking call, waiting for transmission */
  restart:
        ret = lttng_poll_wait(&events, -1);
@@@ -1127,6 -1124,17 +1161,17 @@@ restart_poll
        ERR("consumer return code : %s", lttcomm_get_readable_code(-code));
  
  error:
+       /* Immediately set the consumerd state to stopped */
+       if (consumer_data->type == LTTNG_CONSUMER_KERNEL) {
+               uatomic_set(&kernel_consumerd_state, CONSUMER_ERROR);
+       } else if (consumer_data->type == LTTNG_CONSUMER64_UST ||
+                       consumer_data->type == LTTNG_CONSUMER32_UST) {
+               uatomic_set(&ust_consumerd_state, CONSUMER_ERROR);
+       } else {
+               /* Code flow error... */
+               assert(0);
+       }
        if (consumer_data->err_sock >= 0) {
                ret = close(consumer_data->err_sock);
                if (ret) {
@@@ -1168,8 -1176,6 +1213,8 @@@ static void *thread_manage_apps(void *d
        struct ust_command ust_cmd;
        struct lttng_poll_event events;
  
 +      tracepoint(sessiond_th_apps_start);
 +
        DBG("[thread] Manage application started");
  
        rcu_register_thread();
  
                DBG("Apps thread polling on %d fds", nb_fd);
  
 +              tracepoint(sessiond_th_apps_poll);
 +
                /* Inifinite blocking call, waiting for transmission */
        restart:
                ret = lttng_poll_wait(&events, -1);
                                        ERR("Apps command pipe error");
                                        goto error;
                                } else if (revents & LPOLLIN) {
 +                                      system("sysctl vm.drop_caches=3");
 +                                      tracepoint(ust_register_read_start);
                                        /* Empty pipe */
                                        ret = read(apps_cmd_pipe[0], &ust_cmd, sizeof(ust_cmd));
                                        if (ret < 0 || ret < sizeof(ust_cmd)) {
                                                PERROR("read apps cmd pipe");
                                                goto error;
                                        }
 +                                      tracepoint(ust_register_read_stop);
  
 +                                      tracepoint(ust_register_add_start);
                                        /* Register applicaton to the session daemon */
                                        ret = ust_app_register(&ust_cmd.reg_msg,
                                                        ust_cmd.sock);
                                        } else if (ret < 0) {
                                                break;
                                        }
 +                                      tracepoint(ust_register_add_stop);
  
                                        /*
                                         * Validate UST version compatibility.
                                                update_ust_app(ust_cmd.sock);
                                        }
  
 +                                      tracepoint(ust_register_done_start);
                                        ret = ust_app_register_done(ust_cmd.sock);
                                        if (ret < 0) {
                                                /*
                                                 */
                                                ust_app_unregister(ust_cmd.sock);
                                        } else {
 +                                              tracepoint(ust_register_done_stop);
                                                /*
                                                 * We just need here to monitor the close of the UST
                                                 * socket and poll set monitor those by default.
                                                DBG("Apps with sock %d added to poll set",
                                                                ust_cmd.sock);
                                        }
 -
                                        break;
                                }
                        } else {
                                 * the event at poll_wait.
                                 */
                                if (revents & (LPOLLERR | LPOLLHUP | LPOLLRDHUP)) {
 +                                      tracepoint(ust_unregister_start);
 +
                                        /* Removing from the poll set */
                                        ret = lttng_poll_del(&events, pollfd);
                                        if (ret < 0) {
  
                                        /* Socket closed on remote end. */
                                        ust_app_unregister(pollfd);
 +
 +                                      tracepoint(ust_unregister_stop);
                                        break;
                                }
                        }
@@@ -1327,8 -1321,6 +1372,8 @@@ static void *thread_dispatch_ust_regist
        struct cds_wfq_node *node;
        struct ust_command *ust_cmd = NULL;
  
 +      tracepoint(sessiond_th_dispatch_start);
 +
        DBG("[thread] Dispatch UST command started");
  
        while (!dispatch_thread_exit) {
                futex_nto1_prepare(&ust_cmd_queue.futex);
  
                do {
 +                      tracepoint(sessiond_th_dispatch_block);
 +
                        /* Dequeue command for registration */
                        node = cds_wfq_dequeue_blocking(&ust_cmd_queue.queue);
                        if (node == NULL) {
                                break;
                        }
  
 +                      tracepoint(ust_dispatch_register_start);
 +
                        ust_cmd = caa_container_of(node, struct ust_command, node);
  
                        DBG("Dispatching UST registration pid:%d ppid:%d uid:%d"
                        free(ust_cmd);
                } while (node != NULL);
  
 +              tracepoint(ust_dispatch_register_stop);
 +
                /* Futex wait on queue. Blocking call on futex() */
                futex_nto1_wait(&ust_cmd_queue.futex);
        }
@@@ -1403,8 -1389,6 +1448,8 @@@ static void *thread_registration_apps(v
         */
        struct ust_command *ust_cmd = NULL;
  
 +      tracepoint(sessiond_th_reg_start);
 +
        DBG("[thread] Manage application registration started");
  
        ret = lttcomm_listen_unix_sock(apps_sock);
        while (1) {
                DBG("Accepting application registration");
  
 +              tracepoint(sessiond_th_reg_poll);
 +
                nb_fd = LTTNG_POLL_GETNB(&events);
  
                /* Inifinite blocking call, waiting for transmission */
                                        ERR("Register apps socket poll error");
                                        goto error;
                                } else if (revents & LPOLLIN) {
 +                                      /* Registration starts here. Recording cycles */
 +                                      tracepoint(ust_register_start);
 +
                                        sock = lttcomm_accept_unix_sock(apps_sock);
                                        if (sock < 0) {
                                                goto error;
                                         * barrier with the exchange in cds_wfq_enqueue.
                                         */
                                        futex_nto1_wake(&ust_cmd_queue.futex);
 +
 +                                      tracepoint(ust_register_stop);
                                }
                        }
                }
@@@ -3429,6 -3406,12 +3474,12 @@@ static int process_client_msg(struct co
                        }
                }
  
+               /* Consumer is in an ERROR state. Report back to client */
+               if (uatomic_read(&kernel_consumerd_state) == CONSUMER_ERROR) {
+                       ret = LTTCOMM_NO_KERNCONSUMERD;
+                       goto error;
+               }
                /* Need a session for kernel command */
                if (need_tracing_session) {
                        if (cmd_ctx->session->kernel_session == NULL) {
                                        ret = LTTCOMM_KERN_CONSUMER_FAIL;
                                        goto error;
                                }
+                               uatomic_set(&kernel_consumerd_state, CONSUMER_STARTED);
                        } else {
                                pthread_mutex_unlock(&kconsumer_data.pid_mutex);
                        }
                }
                break;
        case LTTNG_DOMAIN_UST:
        {
+               /* Consumer is in an ERROR state. Report back to client */
+               if (uatomic_read(&ust_consumerd_state) == CONSUMER_ERROR) {
+                       ret = LTTCOMM_NO_USTCONSUMERD;
+                       goto error;
+               }
                if (need_tracing_session) {
                        if (cmd_ctx->session->ust_session == NULL) {
                                ret = create_ust_session(cmd_ctx->session,
                                }
  
                                ust_consumerd64_fd = ustconsumer64_data.cmd_sock;
+                               uatomic_set(&ust_consumerd_state, CONSUMER_STARTED);
                        } else {
                                pthread_mutex_unlock(&ustconsumer64_data.pid_mutex);
                        }
                                        ust_consumerd32_fd = -EINVAL;
                                        goto error;
                                }
                                ust_consumerd32_fd = ustconsumer32_data.cmd_sock;
+                               uatomic_set(&ust_consumerd_state, CONSUMER_STARTED);
                        } else {
                                pthread_mutex_unlock(&ustconsumer32_data.pid_mutex);
                        }
        }
  skip_domain:
  
+       /* Validate consumer daemon state when start/stop trace command */
+       if (cmd_ctx->lsm->cmd_type == LTTNG_START_TRACE ||
+                       cmd_ctx->lsm->cmd_type == LTTNG_STOP_TRACE) {
+               switch (cmd_ctx->lsm->domain.type) {
+               case LTTNG_DOMAIN_UST:
+                       if (uatomic_read(&ust_consumerd_state) != CONSUMER_STARTED) {
+                               ret = LTTCOMM_NO_USTCONSUMERD;
+                               goto error;
+                       }
+                       break;
+               case LTTNG_DOMAIN_KERNEL:
+                       if (uatomic_read(&kernel_consumerd_state) != CONSUMER_STARTED) {
+                               ret = LTTCOMM_NO_KERNCONSUMERD;
+                               goto error;
+                       }
+                       break;
+               }
+       }
        /*
         * Check that the UID or GID match that of the tracing session.
         * The root user can interact with all sessions.
        }
        case LTTNG_ENABLE_CHANNEL:
        {
 +              tracepoint(enable_ust_channel_start);
                ret = cmd_enable_channel(cmd_ctx->session, cmd_ctx->lsm->domain.type,
                                &cmd_ctx->lsm->u.channel.chan);
 +              tracepoint(enable_ust_channel_end);
 +              bench_print_enable_ust_channel();
                break;
        }
        case LTTNG_ENABLE_EVENT:
        {
 +              tracepoint(enable_ust_event_start);
                ret = cmd_enable_event(cmd_ctx->session, cmd_ctx->lsm->domain.type,
                                cmd_ctx->lsm->u.enable.channel_name,
                                &cmd_ctx->lsm->u.enable.event);
 +              tracepoint(enable_ust_event_end);
                break;
        }
        case LTTNG_ENABLE_ALL_EVENT:
        {
                DBG("Enabling all events");
  
 +              tracepoint(enable_ust_event_start);
                ret = cmd_enable_event_all(cmd_ctx->session, cmd_ctx->lsm->domain.type,
                                cmd_ctx->lsm->u.enable.channel_name,
                                cmd_ctx->lsm->u.enable.event.type);
 +              tracepoint(enable_ust_event_end);
                break;
        }
        case LTTNG_LIST_TRACEPOINTS:
        }
        case LTTNG_START_TRACE:
        {
 +              tracepoint(start_ust_start);
                ret = cmd_start_trace(cmd_ctx->session);
 +              tracepoint(start_ust_end);
 +              bench_print_start_ust();
                break;
        }
        case LTTNG_STOP_TRACE:
        }
        case LTTNG_CREATE_SESSION:
        {
 +              tracepoint(create_session_start);
                ret = cmd_create_session(cmd_ctx->lsm->session.name,
                                cmd_ctx->lsm->session.path, &cmd_ctx->creds);
 +              tracepoint(create_session_end);
 +              bench_print_create_session();
                break;
        }
        case LTTNG_DESTROY_SESSION:
        {
 +              tracepoint(destroy_session_start);
                ret = cmd_destroy_session(cmd_ctx->session,
                                cmd_ctx->lsm->session.name);
 +              tracepoint(destroy_session_end);
                /*
                 * Set session to NULL so we do not unlock it after
                 * free.
@@@ -3793,8 -3791,6 +3874,8 @@@ static void *thread_manage_clients(voi
        struct command_ctx *cmd_ctx = NULL;
        struct lttng_poll_event events;
  
 +      tracepoint(sessiond_th_cli_start);
 +
        DBG("[thread] Manage client started");
  
        rcu_register_thread();
        while (1) {
                DBG("Accepting client command ...");
  
 +              tracepoint(sessiond_th_cli_poll);
 +
                nb_fd = LTTNG_POLL_GETNB(&events);
  
                /* Inifinite blocking call, waiting for transmission */
@@@ -4485,8 -4479,6 +4566,8 @@@ int main(int argc, char **argv
        void *status;
        const char *home_path;
  
 +      tracepoint(sessiond_boot_start);
 +
        init_kernel_workarounds();
  
        rcu_register_thread();
                }
        }
  
+       /* Set consumer initial state */
+       kernel_consumerd_state = CONSUMER_STOPPED;
+       ust_consumerd_state = CONSUMER_STOPPED;
        DBG("Client socket path %s", client_unix_sock_path);
        DBG("Application socket path %s", apps_unix_sock_path);
        DBG("LTTng run directory path: %s", rundir);
        /* Set up max poll set size */
        lttng_poll_set_max_size();
  
 +      bench_init();
 +
        /* Create thread to manage the client socket */
        ret = pthread_create(&client_thread, NULL,
                        thread_manage_clients, (void *) NULL);
                goto exit_kernel;
        }
  
 +      tracepoint(sessiond_boot_end);
 +
        ret = pthread_join(kernel_thread, &status);
        if (ret != 0) {
                PERROR("pthread_join");
This page took 0.102422 seconds and 4 git commands to generate.