]> git.ipfire.org Git - thirdparty/lxc.git/commitdiff
commands: handle EINTR 1659/head
authorChristian Brauner <christian.brauner@ubuntu.com>
Tue, 4 Jul 2017 17:16:08 +0000 (19:16 +0200)
committerChristian Brauner <christian.brauner@ubuntu.com>
Sat, 8 Jul 2017 22:14:47 +0000 (00:14 +0200)
Signed-off-by: Christian Brauner <christian.brauner@ubuntu.com>
src/lxc/commands_utils.c
src/lxc/lxccontainer.c
src/lxc/start.c

index fde7da9047303862bd8a7224f2c55938ada7adec..5e589d2af2037daeeeeee631e22b5de0fdfe799e 100644 (file)
@@ -45,13 +45,17 @@ int lxc_cmd_sock_rcv_state(int state_client_fd, int timeout)
        struct lxc_msg msg;
        struct timeval out;
 
-       memset(&out, 0, sizeof(out));
-       out.tv_sec = timeout;
-       ret = setsockopt(state_client_fd, SOL_SOCKET, SO_RCVTIMEO,
-                        (const void *)&out, sizeof(out));
-       if (ret < 0) {
-               SYSERROR("Failed to set %ds timeout on containter state socket", timeout);
-               return -1;
+       if (timeout >= 0) {
+               memset(&out, 0, sizeof(out));
+               out.tv_sec = timeout;
+               ret = setsockopt(state_client_fd, SOL_SOCKET, SO_RCVTIMEO,
+                               (const void *)&out, sizeof(out));
+               if (ret < 0) {
+                       SYSERROR("Failed to set %ds timeout on containter "
+                                "state socket",
+                                timeout);
+                       return -1;
+               }
        }
 
        memset(&msg, 0, sizeof(msg));
@@ -59,8 +63,10 @@ int lxc_cmd_sock_rcv_state(int state_client_fd, int timeout)
 again:
        ret = recv(state_client_fd, &msg, sizeof(msg), 0);
        if (ret < 0) {
-               if (errno == EINTR)
+               if (errno == EINTR) {
+                       TRACE("Caught EINTR; retrying");
                        goto again;
+               }
 
                ERROR("failed to receive message: %s", strerror(errno));
                return -1;
index 75dda44ed97cfc23a0ea83d42c5f6e74f221720c..fa04becb68ecb9d5479c57221f997df25a18ec35 100644 (file)
@@ -702,7 +702,7 @@ static void free_init_cmd(char **argv)
 static int lxc_rcv_status(int state_socket)
 {
         int ret;
-        lxc_state_t state = -1;
+        int state = -1;
         struct timeval timeout = {0};
 
         /* Set 5 second timeout to prevent hanging forever in case something
@@ -716,14 +716,16 @@ static int lxc_rcv_status(int state_socket)
                 return -1;
         }
 
+again:
         /* Receive container state. */
         ret = lxc_abstract_unix_rcv_credential(state_socket, &state,
-                                               sizeof(lxc_state_t));
-        /* Close container state client. */
-        close(state_socket);
-
-        if (ret <= 0)
-                return -1;
+                                               sizeof(int));
+        if (ret <= 0) {
+               if (errno != EINTR)
+                       return -1;
+               TRACE("Caught EINTR; retrying");
+               goto again;
+       }
 
         return state;
 }
index cd9dc18beed44a49b1aeab63ce3dc918011a368c..9a7e462d0b517e9c92b9a460086972d0131b807f 100644 (file)
@@ -384,9 +384,11 @@ static int lxc_serve_state_clients(const char *name,
 
        again:
                ret = send(client->clientfd, &msg, sizeof(msg), 0);
-               if (ret < 0) {
-                       if (errno == EINTR)
+               if (ret <= 0) {
+                       if (errno == EINTR) {
+                               TRACE("Caught EINTR; retrying");
                                goto again;
+                       }
 
                        ERROR("failed to send message to client");
                }
@@ -417,11 +419,16 @@ static int lxc_serve_state_socket_pair(const char *name,
        close(handler->state_socket_pair[0]);
        handler->state_socket_pair[0] = -1;
 
+again:
        ret = lxc_abstract_unix_send_credential(handler->state_socket_pair[1],
                                                &(int){state}, sizeof(int));
-       if (ret != sizeof(int))
+       if (ret != sizeof(int)) {
+               if (errno == EINTR)
+                       goto again;
                SYSERROR("Failed to send state to %d",
                         handler->state_socket_pair[1]);
+               return -1;
+       }
 
        TRACE("Sent container state \"%s\" to %d", lxc_state2str(state),
              handler->state_socket_pair[1]);