]> git.ipfire.org Git - thirdparty/lxc.git/commitdiff
commands: handle epipe
authorSerge Hallyn <serge.hallyn@ubuntu.com>
Tue, 25 Mar 2014 20:50:06 +0000 (15:50 -0500)
committerStéphane Graber <stgraber@ubuntu.com>
Tue, 25 Mar 2014 22:38:39 +0000 (18:38 -0400)
If we start a lxc_wait on a container while it is exiting, it is
possible that we open the command socket, then the command socket
monitor closes all its mainloop sockets and exit, then we send our
credentials. Then we get killed by SIGPIPE.

Handle that case, recognizing that if we get sigpipe then the
container is (now) stopped.

Signed-off-by: Serge Hallyn <serge.hallyn@ubuntu.com>
Acked-by: Stéphane Graber <stgraber@ubuntu.com>
src/lxc/af_unix.c
src/lxc/commands.c

index a2de73e86c621e13e6dcd645d75e0f8f9e171d97..46d8e50fc3aac68f4c50bfe35fd38bdeb1f33c43 100644 (file)
@@ -158,7 +158,7 @@ int lxc_abstract_unix_send_fd(int fd, int sendfd, void *data, size_t size)
        msg.msg_iov = &iov;
        msg.msg_iovlen = 1;
 
-       return sendmsg(fd, &msg, 0);
+       return sendmsg(fd, &msg, MSG_NOSIGNAL);
 }
 
 int lxc_abstract_unix_recv_fd(int fd, int *recvfd, void *data, size_t size)
@@ -230,7 +230,7 @@ int lxc_abstract_unix_send_credential(int fd, void *data, size_t size)
        msg.msg_iov = &iov;
        msg.msg_iovlen = 1;
 
-       return sendmsg(fd, &msg, 0);
+       return sendmsg(fd, &msg, MSG_NOSIGNAL);
 }
 
 int lxc_abstract_unix_rcv_credential(int fd, void *data, size_t size)
index 6b46c2ca74ec70be0c84033b5476b28d87408fb6..b71274c3e250543ceffcd0b2b76e11564acec926 100644 (file)
@@ -263,6 +263,8 @@ static int lxc_cmd(const char *name, struct lxc_cmd_rr *cmd, int *stopped,
 
        ret = lxc_abstract_unix_send_credential(sock, &cmd->req, sizeof(cmd->req));
        if (ret != sizeof(cmd->req)) {
+               if (errno == EPIPE)
+                       goto epipe;
                SYSERROR("command %s failed to send req to '@%s' %d",
                         lxc_cmd_str(cmd->req.cmd), offset, ret);
                if (ret >=0)
@@ -271,8 +273,10 @@ static int lxc_cmd(const char *name, struct lxc_cmd_rr *cmd, int *stopped,
        }
 
        if (cmd->req.datalen > 0) {
-               ret = send(sock, cmd->req.data, cmd->req.datalen, 0);
+               ret = send(sock, cmd->req.data, cmd->req.datalen, MSG_NOSIGNAL);
                if (ret != cmd->req.datalen) {
+                       if (errno == EPIPE)
+                               goto epipe;
                        SYSERROR("command %s failed to send request data to '@%s' %d",
                                 lxc_cmd_str(cmd->req.cmd), offset, ret);
                        if (ret >=0)
@@ -289,6 +293,11 @@ out:
                cmd->rsp.ret = sock;
 
        return ret;
+
+epipe:
+       close(sock);
+       *stopped = 1;
+       return 0;
 }
 
 int lxc_try_cmd(const char *name, const char *lxcpath)