Update and fix UST register and session creation
[lttng-tools.git] / ltt-sessiond / main.c
index edbdd643a84f5e1c69b3118663af7fafb2b274fa..a3335292bc0760746a701f0426d79a6a011dd34a 100644 (file)
@@ -48,7 +48,7 @@
 #include "traceable-app.h"
 #include "ust-ctl.h"
 #include "utils.h"
-#include "ust-comm.h"
+#include "ust-ctl.h"
 
 /* Const values */
 const char default_home_dir[] = DEFAULT_HOME_DIR;
@@ -214,7 +214,7 @@ static void cleanup(void)
        DBG("Cleaning up");
 
        /* <fun> */
-       MSG("\n%c[%d;%dm*** assert failed *** ==> %c[%dm%c[%d;%dm"
+       MSG("%c[%d;%dm*** assert failed *** ==> %c[%dm%c[%d;%dm"
                "Matthew, BEET driven development works!%c[%dm",
                27, 1, 31, 27, 0, 27, 1, 33, 27, 0);
        /* </fun> */
@@ -252,8 +252,10 @@ static void cleanup(void)
        DBG("Closing kernel fd");
        close(kernel_tracer_fd);
 
-       DBG("Unloading kernel modules");
-       modprobe_remove_kernel_modules();
+       if (is_root) {
+               DBG("Unloading kernel modules");
+               modprobe_remove_kernel_modules();
+       }
 }
 
 /*
@@ -404,34 +406,6 @@ error:
 }
 
 #ifdef DISABLED
-/*
- * Return a socket connected to the libust communication socket of the
- * application identified by the pid.
- *
- * If the pid is not found in the traceable list, return -1 to indicate error.
- */
-static int ust_connect_app(pid_t pid)
-{
-       int sock;
-       struct ltt_traceable_app *lta;
-
-       DBG("Connect to application pid %d", pid);
-
-       lta = find_app_by_pid(pid);
-       if (lta == NULL) {
-               /* App not found */
-               DBG("Application pid %d not found", pid);
-               return -1;
-       }
-
-       sock = ustctl_connect_pid(lta->pid);
-       if (sock < 0) {
-               ERR("Fail connecting to the PID %d", pid);
-       }
-
-       return sock;
-}
-
 /*
  * Notify apps by writing 42 to a named pipe using name. Every applications
  * waiting for a ltt-sessiond will be notified and re-register automatically to
@@ -828,16 +802,25 @@ error:
  *
  * The first two fds must be there at all time.
  */
-static int update_apps_cmd_pollfd(unsigned int nb_fd, struct pollfd **pollfd)
+static int update_apps_cmd_pollfd(unsigned int nb_fd, unsigned int old_nb_fd,
+               struct pollfd **pollfd)
 {
+       int i, count;
+       struct pollfd *old_pollfd = NULL;
+
        /* Can't accept pollfd less than 2 */
        if (nb_fd < 2) {
                goto end;
        }
 
-       *pollfd = realloc(*pollfd, nb_fd * sizeof(struct pollfd));
+       if (*pollfd) {
+               /* Save pointer */
+               old_pollfd = *pollfd;
+       }
+
+       *pollfd = malloc(nb_fd * sizeof(struct pollfd));
        if (*pollfd == NULL) {
-               perror("realloc manage apps pollfd");
+               perror("malloc manage apps pollfd");
                goto error;
        }
 
@@ -847,30 +830,36 @@ static int update_apps_cmd_pollfd(unsigned int nb_fd, struct pollfd **pollfd)
        (*pollfd)[1].fd = apps_cmd_pipe[0];
        (*pollfd)[1].events = POLLIN;
 
+       /* Start count after the two pipes below */
+       count = 2;
+       for (i = 2; i < old_nb_fd; i++) {
+               /* Add to new pollfd */
+               if (old_pollfd[i].fd != -1) {
+                       (*pollfd)[count].fd = old_pollfd[i].fd;
+                       (*pollfd)[count].events = POLLHUP | POLLNVAL | POLLERR;
+                       count++;
+               }
+
+               if (count > nb_fd) {
+                       ERR("Updating poll fd wrong size");
+                       goto error;
+               }
+       }
+
+       /* Destroy old pollfd */
+       free(old_pollfd);
+
        DBG("Apps cmd pollfd realloc of size %d", nb_fd);
 
 end:
        return 0;
 
 error:
+       /* Destroy old pollfd */
+       free(old_pollfd);
        return -1;
 }
 
-/*
- * Send registration done packet to the application.
- */
-static int send_ust_register_done(int sock)
-{
-       struct lttcomm_ust_msg lum;
-
-       DBG("Sending register done command to %d", sock);
-
-       lum.cmd = LTTNG_UST_REGISTER_DONE;
-       lum.handle = LTTNG_UST_ROOT_HANDLE;
-
-       return ustcomm_send_command(sock, &lum);
-}
-
 /*
  * This thread manage application communication.
  */
@@ -895,16 +884,17 @@ static void *thread_manage_apps(void *data)
 
                /* The pollfd struct must be updated */
                if (update_poll_flag) {
-                       ret = update_apps_cmd_pollfd(nb_fd, &pollfd);
+                       ret = update_apps_cmd_pollfd(nb_fd, ARRAY_SIZE(pollfd), &pollfd);
                        if (ret < 0) {
                                /* malloc failed so we quit */
                                goto error;
                        }
+
                        if (ust_cmd.sock != -1) {
                                /* Update pollfd with the new UST socket */
                                DBG("Adding sock %d to apps cmd pollfd", ust_cmd.sock);
                                pollfd[nb_fd - 1].fd = ust_cmd.sock;
-                               pollfd[nb_fd - 1].events = POLLHUP | POLLNVAL;
+                               pollfd[nb_fd - 1].events = POLLHUP | POLLNVAL | POLLERR;
                                ust_cmd.sock = -1;
                        }
                }
@@ -921,31 +911,36 @@ static void *thread_manage_apps(void *data)
                /* Thread quit pipe has been closed. Killing thread. */
                if (pollfd[0].revents == POLLNVAL) {
                        goto error;
-               } else if (pollfd[1].revents == POLLERR) {
-                       ERR("Apps command pipe poll error");
-                       goto error;
-               } else if (pollfd[1].revents == POLLIN) {
-                       /* 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");
+               } else {
+                       /* apps_cmd_pipe pipe events */
+                       switch (pollfd[1].revents) {
+                       case POLLERR:
+                               ERR("Apps command pipe poll error");
                                goto error;
-                       }
+                       case POLLIN:
+                               /* 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;
+                               }
 
-                       /* Register applicaton to the session daemon */
-                       ret = register_traceable_app(&ust_cmd.reg_msg, ust_cmd.sock);
-                       if (ret < 0) {
-                               /* Only critical ENOMEM error can be returned here */
-                               goto error;
-                       }
+                               /* Register applicaton to the session daemon */
+                               ret = register_traceable_app(&ust_cmd.reg_msg, ust_cmd.sock);
+                               if (ret < 0) {
+                                       /* Only critical ENOMEM error can be returned here */
+                                       goto error;
+                               }
 
-                       ret = send_ust_register_done(ust_cmd.sock);
-                       if (ret < 0) {
-                               /*
-                                * If the registration is not possible, we simply unregister
-                                * the apps and continue
-                                */
-                               unregister_traceable_app(ust_cmd.sock);
+                               ret = ustctl_register_done(ust_cmd.sock);
+                               if (ret < 0) {
+                                       /*
+                                        * If the registration is not possible, we simply unregister
+                                        * the apps and continue
+                                        */
+                                       unregister_traceable_app(ust_cmd.sock);
+                               }
+                               break;
                        }
                }
 
@@ -953,11 +948,15 @@ static void *thread_manage_apps(void *data)
                for (i = 2; i < count; i++) {
                        /* Apps socket is closed/hungup */
                        switch (pollfd[i].revents) {
-                       case POLLNVAL:
+                       case POLLERR:
                        case POLLHUP:
+                       case POLLNVAL:
                                /* Pipe closed */
                                unregister_traceable_app(pollfd[i].fd);
+                               /* Indicate to remove this fd from the pollfd */
+                               pollfd[i].fd = -1;
                                nb_fd--;
+                               break;
                        }
                }
 
@@ -1003,8 +1002,12 @@ static void *thread_dispatch_ust_registration(void *data)
 
                        ust_cmd = caa_container_of(node, struct ust_command, node);
 
-                       DBG("Dispatching UST registration pid:%d sock:%d",
-                                       ust_cmd->reg_msg.pid, ust_cmd->sock);
+                       DBG("Dispatching UST registration pid:%d ppid:%d uid:%d"
+                                       " gid:%d sock:%d name:%s (version %d.%d)",
+                                       ust_cmd->reg_msg.pid, ust_cmd->reg_msg.ppid,
+                                       ust_cmd->reg_msg.uid, ust_cmd->reg_msg.gid,
+                                       ust_cmd->sock, ust_cmd->reg_msg.name,
+                                       ust_cmd->reg_msg.major, ust_cmd->reg_msg.minor);
                        /*
                         * Inform apps thread of the new application registration. This
                         * call is blocking so we can be assured that the data will be read
@@ -1102,8 +1105,12 @@ static void *thread_registration_apps(void *data)
                 */
                ret = lttcomm_recv_unix_sock(sock, &ust_cmd->reg_msg,
                                sizeof(struct ust_register_msg));
-               if (ret < 0 || ret != sizeof(struct ust_register_msg)) {
-                       perror("lttcomm_recv_unix_sock register apps");
+               if (ret < 0 || ret < sizeof(struct ust_register_msg)) {
+                       if (ret < 0) {
+                               perror("lttcomm_recv_unix_sock register apps");
+                       } else {
+                               ERR("Wrong size received on apps register");
+                       }
                        free(ust_cmd);
                        close(sock);
                        continue;
@@ -1111,6 +1118,12 @@ static void *thread_registration_apps(void *data)
 
                ust_cmd->sock = sock;
 
+               DBG("UST registration received with pid:%d ppid:%d uid:%d"
+                               " gid:%d sock:%d name:%s (version %d.%d)",
+                               ust_cmd->reg_msg.pid, ust_cmd->reg_msg.ppid,
+                               ust_cmd->reg_msg.uid, ust_cmd->reg_msg.gid,
+                               ust_cmd->sock, ust_cmd->reg_msg.name,
+                               ust_cmd->reg_msg.major, ust_cmd->reg_msg.minor);
                /*
                 * Lock free enqueue the registration request.
                 * The red pill has been taken! This apps will be part of the *system*
@@ -1122,9 +1135,6 @@ static void *thread_registration_apps(void *data)
                 * Implicit memory barrier with the exchange in cds_wfq_enqueue.
                 */
                futex_nto1_wake(&ust_cmd_queue.futex);
-
-               DBG("Thread manage apps informed of queued node with sock:%d pid:%d",
-                               sock, ust_cmd->reg_msg.pid);
        }
 
 error:
@@ -1541,6 +1551,43 @@ error:
        return NULL;
 }
 
+/*
+ * Create an UST session and add it to the session ust list.
+ */
+static int create_ust_session(pid_t pid, struct ltt_session *session)
+{
+       int ret = -1;
+       struct ltt_ust_session *lus;
+
+       DBG("Creating UST session");
+
+       lus = trace_ust_create_session(session->path, pid);
+       if (lus == NULL) {
+               goto error;
+       }
+
+       ret = mkdir_recursive(lus->path, S_IRWXU | S_IRWXG,
+                       geteuid(), allowed_group());
+       if (ret < 0) {
+               if (ret != -EEXIST) {
+                       ERR("Trace directory creation error");
+                       goto error;
+               }
+       }
+
+       /* Create session on the UST tracer */
+       ret = ustctl_create_session(lus);
+       if (ret < 0) {
+               goto error;
+       }
+
+       return 0;
+
+error:
+       free(lus);
+       return ret;
+}
+
 /*
  * Create a kernel tracer session then create the default channel.
  */
@@ -1716,7 +1763,6 @@ static int process_client_msg(struct command_ctx *cmd_ctx)
                                goto error;
                        }
                }
-
                /* Need a session for kernel command */
                switch (cmd_ctx->lsm->cmd_type) {
                case LTTNG_CALIBRATE:
@@ -1731,9 +1777,7 @@ static int process_client_msg(struct command_ctx *cmd_ctx)
                                        ret = LTTCOMM_KERN_SESS_FAIL;
                                        goto error;
                                }
-
                                /* Start the kernel consumer daemon */
-
                                if (kconsumerd_pid == 0 &&
                                                cmd_ctx->lsm->cmd_type != LTTNG_REGISTER_CONSUMER) {
                                        ret = start_kconsumerd();
@@ -1954,8 +1998,9 @@ static int process_client_msg(struct command_ctx *cmd_ctx)
 
                        kernel_wait_quiescent(kernel_tracer_fd);
                        break;
+               case LTTNG_DOMAIN_UST_PID:
+                       break;
                default:
-                       /* TODO: Userspace tracing */
                        ret = LTTCOMM_NOT_IMPLEMENTED;
                        goto error;
                }
@@ -2339,7 +2384,7 @@ static int process_client_msg(struct command_ctx *cmd_ctx)
                        nb_dom++;
                }
 
-               nb_dom += cmd_ctx->session->ust_trace_count;
+               nb_dom += cmd_ctx->session->ust_session_list.count;
 
                ret = setup_lttng_msg(cmd_ctx, sizeof(struct lttng_domain) * nb_dom);
                if (ret < 0) {
This page took 0.031785 seconds and 5 git commands to generate.