Fix: handle EINTR for every read()
[lttng-tools.git] / src / bin / lttng-sessiond / main.c
index 7e9f9dc643b3c3f97fa52f261f47f14c11bff9a7..477a9413b71692d8630572dc8ab6de49b5534bad 100644 (file)
@@ -461,7 +461,7 @@ static void cleanup(void)
 static int send_unix_sock(int sock, void *buf, size_t len)
 {
        /* Check valid length */
-       if (len <= 0) {
+       if (len == 0) {
                return -1;
        }
 
@@ -691,36 +691,40 @@ static void *thread_manage_kernel(void *data)
 
        DBG("[thread] Thread manage kernel started");
 
+       /*
+        * This first step of the while is to clean this structure which could free
+        * non NULL pointers so zero it before the loop.
+        */
+       memset(&events, 0, sizeof(events));
+
        if (testpoint(thread_manage_kernel)) {
                goto error_testpoint;
        }
 
        health_code_update(&health_thread_kernel);
 
-       ret = create_thread_poll_set(&events, 2);
-       if (ret < 0) {
-               goto error_poll_create;
-       }
-
-       ret = lttng_poll_add(&events, kernel_poll_pipe[0], LPOLLIN);
-       if (ret < 0) {
-               goto error;
-       }
-
        if (testpoint(thread_manage_kernel_before_loop)) {
-               goto error;
+               goto error_testpoint;
        }
 
        while (1) {
                health_code_update(&health_thread_kernel);
 
                if (update_poll_flag == 1) {
-                       /*
-                        * Reset number of fd in the poll set. Always 2 since there is the thread
-                        * quit pipe and the kernel pipe.
-                        */
-                       events.nb_fd = 2;
+                       /* Clean events object. We are about to populate it again. */
+                       lttng_poll_clean(&events);
+
+                       ret = create_thread_poll_set(&events, 2);
+                       if (ret < 0) {
+                               goto error_poll_create;
+                       }
+
+                       ret = lttng_poll_add(&events, kernel_poll_pipe[0], LPOLLIN);
+                       if (ret < 0) {
+                               goto error;
+                       }
 
+                       /* This will add the available kernel channel if any. */
                        ret = update_kernel_poll(&events);
                        if (ret < 0) {
                                goto error;
@@ -728,12 +732,7 @@ static void *thread_manage_kernel(void *data)
                        update_poll_flag = 0;
                }
 
-               nb_fd = LTTNG_POLL_GETNB(&events);
-
-               DBG("Thread kernel polling on %d fds", nb_fd);
-
-               /* Zeroed the poll events */
-               lttng_poll_reset(&events);
+               DBG("Thread kernel polling on %d fds", LTTNG_POLL_GETNB(&events));
 
                /* Poll infinite value of time */
        restart:
@@ -755,6 +754,8 @@ static void *thread_manage_kernel(void *data)
                        continue;
                }
 
+               nb_fd = ret;
+
                for (i = 0; i < nb_fd; i++) {
                        /* Fetch once the poll data */
                        revents = LTTNG_POLL_GETEV(&events, i);
@@ -771,7 +772,13 @@ static void *thread_manage_kernel(void *data)
 
                        /* Check for data on kernel pipe */
                        if (pollfd == kernel_poll_pipe[0] && (revents & LPOLLIN)) {
-                               ret = read(kernel_poll_pipe[0], &tmp, 1);
+                               do {
+                                       ret = read(kernel_poll_pipe[0], &tmp, 1);
+                               } while (ret < 0 && errno == EINTR);
+                               /*
+                                * Ret value is useless here, if this pipe gets any actions an
+                                * update is required anyway.
+                                */
                                update_poll_flag = 1;
                                continue;
                        } else {
@@ -886,8 +893,6 @@ static void *thread_manage_consumer(void *data)
                goto error;
        }
 
-       nb_fd = LTTNG_POLL_GETNB(&events);
-
        health_code_update(&consumer_data->health);
 
        /* Inifinite blocking call, waiting for transmission */
@@ -910,6 +915,8 @@ restart:
                goto error;
        }
 
+       nb_fd = ret;
+
        for (i = 0; i < nb_fd; i++) {
                /* Fetch once the poll data */
                revents = LTTNG_POLL_GETEV(&events, i);
@@ -987,9 +994,6 @@ restart:
 
        health_code_update(&consumer_data->health);
 
-       /* Update number of fd */
-       nb_fd = LTTNG_POLL_GETNB(&events);
-
        /* Inifinite blocking call, waiting for transmission */
 restart_poll:
        health_poll_update(&consumer_data->health);
@@ -1005,6 +1009,8 @@ restart_poll:
                goto error;
        }
 
+       nb_fd = ret;
+
        for (i = 0; i < nb_fd; i++) {
                /* Fetch once the poll data */
                revents = LTTNG_POLL_GETEV(&events, i);
@@ -1126,12 +1132,7 @@ static void *thread_manage_apps(void *data)
        health_code_update(&health_thread_app_manage);
 
        while (1) {
-               /* Zeroed the events structure */
-               lttng_poll_reset(&events);
-
-               nb_fd = LTTNG_POLL_GETNB(&events);
-
-               DBG("Apps thread polling on %d fds", nb_fd);
+               DBG("Apps thread polling on %d fds", LTTNG_POLL_GETNB(&events));
 
                /* Inifinite blocking call, waiting for transmission */
        restart:
@@ -1148,6 +1149,8 @@ static void *thread_manage_apps(void *data)
                        goto error;
                }
 
+               nb_fd = ret;
+
                for (i = 0; i < nb_fd; i++) {
                        /* Fetch once the poll data */
                        revents = LTTNG_POLL_GETEV(&events, i);
@@ -1169,7 +1172,9 @@ static void *thread_manage_apps(void *data)
                                        goto error;
                                } else if (revents & LPOLLIN) {
                                        /* Empty pipe */
-                                       ret = read(apps_cmd_pipe[0], &ust_cmd, sizeof(ust_cmd));
+                                       do {
+                                               ret = read(apps_cmd_pipe[0], &ust_cmd, sizeof(ust_cmd));
+                                       } while (ret < 0 && errno == EINTR);
                                        if (ret < 0 || ret < sizeof(ust_cmd)) {
                                                PERROR("read apps cmd pipe");
                                                goto error;
@@ -1405,8 +1410,6 @@ static void *thread_registration_apps(void *data)
        while (1) {
                DBG("Accepting application registration");
 
-               nb_fd = LTTNG_POLL_GETNB(&events);
-
                /* Inifinite blocking call, waiting for transmission */
        restart:
                health_poll_update(&health_thread_app_reg);
@@ -1422,6 +1425,8 @@ static void *thread_registration_apps(void *data)
                        goto error;
                }
 
+               nb_fd = ret;
+
                for (i = 0; i < nb_fd; i++) {
                        health_code_update(&health_thread_app_reg);
 
@@ -1684,10 +1689,10 @@ error:
 static int join_consumer_thread(struct consumer_data *consumer_data)
 {
        void *status;
-       int ret;
 
        /* Consumer pid must be a real one. */
        if (consumer_data->pid > 0) {
+               int ret;
                ret = kill(consumer_data->pid, SIGTERM);
                if (ret) {
                        ERR("Error killing consumer daemon");
@@ -1866,7 +1871,7 @@ error:
  */
 static int start_consumerd(struct consumer_data *consumer_data)
 {
-       int ret, err;
+       int ret;
 
        /*
         * Set the listen() state on the socket since there is a possible race
@@ -1909,6 +1914,8 @@ end:
 error:
        /* Cleanup already created socket on error. */
        if (consumer_data->err_sock >= 0) {
+               int err;
+
                err = close(consumer_data->err_sock);
                if (err < 0) {
                        PERROR("close consumer data error socket");
@@ -2982,8 +2989,6 @@ static void *thread_manage_health(void *data)
        while (1) {
                DBG("Health check ready");
 
-               nb_fd = LTTNG_POLL_GETNB(&events);
-
                /* Inifinite blocking call, waiting for transmission */
 restart:
                ret = lttng_poll_wait(&events, -1);
@@ -2997,6 +3002,8 @@ restart:
                        goto error;
                }
 
+               nb_fd = ret;
+
                for (i = 0; i < nb_fd; i++) {
                        /* Fetch once the poll data */
                        revents = LTTNG_POLL_GETEV(&events, i);
@@ -3181,8 +3188,6 @@ static void *thread_manage_clients(void *data)
        while (1) {
                DBG("Accepting client command ...");
 
-               nb_fd = LTTNG_POLL_GETNB(&events);
-
                /* Inifinite blocking call, waiting for transmission */
        restart:
                health_poll_update(&health_thread_cmd);
@@ -3198,6 +3203,8 @@ static void *thread_manage_clients(void *data)
                        goto error;
                }
 
+               nb_fd = ret;
+
                for (i = 0; i < nb_fd; i++) {
                        /* Fetch once the poll data */
                        revents = LTTNG_POLL_GETEV(&events, i);
@@ -3855,7 +3862,7 @@ int main(int argc, char **argv)
 
        /* Parse arguments */
        progname = argv[0];
-       if ((ret = parse_args(argc, argv) < 0)) {
+       if ((ret = parse_args(argc, argv)) < 0) {
                goto error;
        }
 
This page took 0.027093 seconds and 4 git commands to generate.