From: Christian Brauner Date: Tue, 4 Jul 2017 17:16:08 +0000 (+0200) Subject: commands: handle EINTR X-Git-Tag: lxc-2.1.0~57^2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=refs%2Fpull%2F1659%2Fhead;p=thirdparty%2Flxc.git commands: handle EINTR Signed-off-by: Christian Brauner --- diff --git a/src/lxc/commands_utils.c b/src/lxc/commands_utils.c index fde7da904..5e589d2af 100644 --- a/src/lxc/commands_utils.c +++ b/src/lxc/commands_utils.c @@ -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; diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c index 75dda44ed..fa04becb6 100644 --- a/src/lxc/lxccontainer.c +++ b/src/lxc/lxccontainer.c @@ -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; } diff --git a/src/lxc/start.c b/src/lxc/start.c index cd9dc18be..9a7e462d0 100644 --- a/src/lxc/start.c +++ b/src/lxc/start.c @@ -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]);