From ee8377bd917a0fb9cc528187ffc6e2cd851afc4b Mon Sep 17 00:00:00 2001 From: Christian Brauner Date: Tue, 4 Jul 2017 19:16:08 +0200 Subject: [PATCH] commands: handle EINTR Signed-off-by: Christian Brauner --- src/lxc/commands_utils.c | 22 ++++++++++++++-------- src/lxc/lxccontainer.c | 16 +++++++++------- src/lxc/start.c | 13 ++++++++++--- 3 files changed, 33 insertions(+), 18 deletions(-) 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]); -- 2.47.2