Merge pull request #2584 from brauner/2018-09-03/bugfixes

commands: switch to setting errno and returning -1
This commit is contained in:
Wolfgang Bumiller 2018-09-04 14:45:55 +02:00 committed by GitHub
commit a21ed5555d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 111 additions and 91 deletions

View File

@ -97,7 +97,7 @@ static const char *lxc_cmd_str(lxc_cmd_t cmd)
}; };
if (cmd >= LXC_CMD_MAX) if (cmd >= LXC_CMD_MAX)
return "Unknown cmd"; return "Invalid request";
return cmdname[cmd]; return cmdname[cmd];
} }
@ -130,7 +130,7 @@ static int lxc_cmd_rsp_recv(int sock, struct lxc_cmd_rr *cmd)
lxc_cmd_str(cmd->req.cmd)); lxc_cmd_str(cmd->req.cmd));
if (errno == ECONNRESET) if (errno == ECONNRESET)
return -ECONNRESET; return -1;
return -1; return -1;
} }
@ -147,10 +147,12 @@ static int lxc_cmd_rsp_recv(int sock, struct lxc_cmd_rr *cmd)
rspdata = malloc(sizeof(*rspdata)); rspdata = malloc(sizeof(*rspdata));
if (!rspdata) { if (!rspdata) {
errno = ENOMEM;
ERROR("Failed to allocate response buffer for command \"%s\"", ERROR("Failed to allocate response buffer for command \"%s\"",
lxc_cmd_str(cmd->req.cmd)); lxc_cmd_str(cmd->req.cmd));
return -ENOMEM; return -1;
} }
rspdata->masterfd = rspfd; rspdata->masterfd = rspfd;
rspdata->ttynum = PTR_TO_INT(rsp->data); rspdata->ttynum = PTR_TO_INT(rsp->data);
rsp->data = rspdata; rsp->data = rspdata;
@ -164,10 +166,9 @@ static int lxc_cmd_rsp_recv(int sock, struct lxc_cmd_rr *cmd)
if ((rsp->datalen > LXC_CMD_DATA_MAX) && if ((rsp->datalen > LXC_CMD_DATA_MAX) &&
(cmd->req.cmd != LXC_CMD_CONSOLE_LOG)) { (cmd->req.cmd != LXC_CMD_CONSOLE_LOG)) {
errno = EFBIG; ERROR("Response data for command \"%s\" is too long: %d bytes > %d",
SYSERROR("Response data for command \"%s\" is too long: %d bytes > %d",
lxc_cmd_str(cmd->req.cmd), rsp->datalen, LXC_CMD_DATA_MAX); lxc_cmd_str(cmd->req.cmd), rsp->datalen, LXC_CMD_DATA_MAX);
return -EFBIG; return -1;
} }
if (cmd->req.cmd == LXC_CMD_CONSOLE_LOG) { if (cmd->req.cmd == LXC_CMD_CONSOLE_LOG) {
@ -178,17 +179,16 @@ static int lxc_cmd_rsp_recv(int sock, struct lxc_cmd_rr *cmd)
} }
if (!rsp->data) { if (!rsp->data) {
errno = ENOMEM; errno = ENOMEM;
SYSERROR("Failed to allocate response buffer for command \"%s\"", ERROR("Failed to allocate response buffer for command \"%s\"",
lxc_cmd_str(cmd->req.cmd)); lxc_cmd_str(cmd->req.cmd));
return -ENOMEM; return -1;
} }
ret = recv(sock, rsp->data, rsp->datalen, 0); ret = lxc_recv_nointr(sock, rsp->data, rsp->datalen, 0);
if (ret != rsp->datalen) { if (ret != rsp->datalen) {
SYSERROR("Failed to receive response data for command \"%s\"", SYSERROR("Failed to receive response data for command \"%s\"",
lxc_cmd_str(cmd->req.cmd)); lxc_cmd_str(cmd->req.cmd));
if (ret >= 0) return -1;
ret = -1;
} }
return ret; return ret;
@ -206,7 +206,8 @@ static int lxc_cmd_rsp_send(int fd, struct lxc_cmd_rsp *rsp)
{ {
ssize_t ret; ssize_t ret;
ret = send(fd, rsp, sizeof(*rsp), MSG_NOSIGNAL); errno = EMSGSIZE;
ret = lxc_send_nointr(fd, rsp, sizeof(*rsp), MSG_NOSIGNAL);
if (ret < 0 || (size_t)ret != sizeof(*rsp)) { if (ret < 0 || (size_t)ret != sizeof(*rsp)) {
SYSERROR("Failed to send command response %zd", ret); SYSERROR("Failed to send command response %zd", ret);
return -1; return -1;
@ -215,7 +216,8 @@ static int lxc_cmd_rsp_send(int fd, struct lxc_cmd_rsp *rsp)
if (!rsp->data || rsp->datalen <= 0) if (!rsp->data || rsp->datalen <= 0)
return 0; return 0;
ret = send(fd, rsp->data, rsp->datalen, MSG_NOSIGNAL); errno = EMSGSIZE;
ret = lxc_send_nointr(fd, rsp->data, rsp->datalen, MSG_NOSIGNAL);
if (ret < 0 || ret != (ssize_t)rsp->datalen) { if (ret < 0 || ret != (ssize_t)rsp->datalen) {
SYSWARN("Failed to send command response data %zd", ret); SYSWARN("Failed to send command response data %zd", ret);
return -1; return -1;
@ -227,51 +229,35 @@ static int lxc_cmd_rsp_send(int fd, struct lxc_cmd_rsp *rsp)
static int lxc_cmd_send(const char *name, struct lxc_cmd_rr *cmd, static int lxc_cmd_send(const char *name, struct lxc_cmd_rr *cmd,
const char *lxcpath, const char *hashed_sock_name) const char *lxcpath, const char *hashed_sock_name)
{ {
int client_fd; int client_fd, saved_errno;
ssize_t ret = -1; ssize_t ret = -1;
client_fd = lxc_cmd_connect(name, lxcpath, hashed_sock_name, "command"); client_fd = lxc_cmd_connect(name, lxcpath, hashed_sock_name, "command");
if (client_fd < 0) { if (client_fd < 0)
if (client_fd == -ECONNREFUSED)
return -ECONNREFUSED;
return -1; return -1;
}
ret = lxc_abstract_unix_send_credential(client_fd, &cmd->req, ret = lxc_abstract_unix_send_credential(client_fd, &cmd->req,
sizeof(cmd->req)); sizeof(cmd->req));
if (ret < 0 ) { if (ret < 0 || (size_t)ret != sizeof(cmd->req))
if (errno == EPIPE) { goto on_error;
close(client_fd);
return -EPIPE;
}
close(client_fd);
return -1;
}
if ((size_t)ret != sizeof(cmd->req)) {
close(client_fd);
return -EMSGSIZE;
}
if (cmd->req.datalen <= 0) if (cmd->req.datalen <= 0)
return client_fd; return client_fd;
ret = send(client_fd, cmd->req.data, cmd->req.datalen, MSG_NOSIGNAL); errno = EMSGSIZE;
if (ret < 0 || ret != (ssize_t)cmd->req.datalen) { ret = lxc_send_nointr(client_fd, (void *)cmd->req.data,
close(client_fd); cmd->req.datalen, MSG_NOSIGNAL);
if (ret < 0 || ret != (ssize_t)cmd->req.datalen)
if (errno == EPIPE) goto on_error;
return -EPIPE;
if (ret >= 0)
return -EMSGSIZE;
return -1;
}
return client_fd; return client_fd;
on_error:
saved_errno = errno;
close(client_fd);
errno = saved_errno;
return -1;
} }
/* /*
@ -296,7 +282,7 @@ static int lxc_cmd_send(const char *name, struct lxc_cmd_rr *cmd,
static int lxc_cmd(const char *name, struct lxc_cmd_rr *cmd, int *stopped, static int lxc_cmd(const char *name, struct lxc_cmd_rr *cmd, int *stopped,
const char *lxcpath, const char *hashed_sock_name) const char *lxcpath, const char *hashed_sock_name)
{ {
int client_fd; int client_fd, saved_errno;
int ret = -1; int ret = -1;
bool stay_connected = false; bool stay_connected = false;
@ -311,24 +297,27 @@ static int lxc_cmd(const char *name, struct lxc_cmd_rr *cmd, int *stopped,
SYSTRACE("Command \"%s\" failed to connect command socket", SYSTRACE("Command \"%s\" failed to connect command socket",
lxc_cmd_str(cmd->req.cmd)); lxc_cmd_str(cmd->req.cmd));
if (client_fd == -ECONNREFUSED) if (errno == ECONNREFUSED)
*stopped = 1; *stopped = 1;
if (client_fd == -EPIPE) { if (errno == EPIPE) {
*stopped = 1; *stopped = 1;
client_fd = 0; client_fd = 0;
} }
return client_fd; return -1;
} }
ret = lxc_cmd_rsp_recv(client_fd, cmd); ret = lxc_cmd_rsp_recv(client_fd, cmd);
if (ret == -ECONNRESET) if (ret < 0 && errno == ECONNRESET)
*stopped = 1; *stopped = 1;
if (!stay_connected || ret <= 0) if (!stay_connected || ret <= 0)
if (client_fd >= 0) if (client_fd >= 0) {
saved_errno = errno;
close(client_fd); close(client_fd);
errno = saved_errno;
}
if (stay_connected && ret > 0) if (stay_connected && ret > 0)
cmd->rsp.ret = client_fd; cmd->rsp.ret = client_fd;
@ -1181,7 +1170,7 @@ static int lxc_cmd_handler(int fd, uint32_t events, void *data,
goto out_close; goto out_close;
} }
ret = recv(fd, reqdata, req.datalen, 0); ret = lxc_recv_nointr(fd, reqdata, req.datalen, 0);
if (ret != req.datalen) { if (ret != req.datalen) {
WARN("Failed to receive full command request. Ignoring " WARN("Failed to receive full command request. Ignoring "
"request for \"%s\"", lxc_cmd_str(req.cmd)); "request for \"%s\"", lxc_cmd_str(req.cmd));

View File

@ -32,6 +32,7 @@
#include "commands.h" #include "commands.h"
#include "commands_utils.h" #include "commands_utils.h"
#include "initutils.h" #include "initutils.h"
#include "file_utils.h"
#include "log.h" #include "log.h"
#include "lxclock.h" #include "lxclock.h"
#include "monitor.h" #include "monitor.h"
@ -61,14 +62,8 @@ int lxc_cmd_sock_rcv_state(int state_client_fd, int timeout)
memset(&msg, 0, sizeof(msg)); memset(&msg, 0, sizeof(msg));
again: ret = lxc_recv_nointr(state_client_fd, &msg, sizeof(msg), 0);
ret = recv(state_client_fd, &msg, sizeof(msg), 0);
if (ret < 0) { if (ret < 0) {
if (errno == EINTR) {
TRACE("Caught EINTR; retrying");
goto again;
}
SYSERROR("Failed to receive message"); SYSERROR("Failed to receive message");
return -1; return -1;
} }
@ -178,11 +173,8 @@ int lxc_cmd_connect(const char *name, const char *lxcpath,
/* Get new client fd. */ /* Get new client fd. */
client_fd = lxc_abstract_unix_connect(path); client_fd = lxc_abstract_unix_connect(path);
if (client_fd < 0) { if (client_fd < 0)
if (errno == ECONNREFUSED)
return -ECONNREFUSED;
return -1; return -1;
}
return client_fd; return client_fd;
} }

View File

@ -106,6 +106,17 @@ again:
return ret; return ret;
} }
ssize_t lxc_send_nointr(int sockfd, void *buf, size_t len, int flags)
{
ssize_t ret;
again:
ret = send(sockfd, buf, len, flags);
if (ret < 0 && errno == EINTR)
goto again;
return ret;
}
ssize_t lxc_read_nointr(int fd, void *buf, size_t count) ssize_t lxc_read_nointr(int fd, void *buf, size_t count)
{ {
ssize_t ret; ssize_t ret;
@ -117,6 +128,17 @@ again:
return ret; return ret;
} }
ssize_t lxc_recv_nointr(int sockfd, void *buf, size_t len, int flags)
{
ssize_t ret;
again:
ret = recv(sockfd, buf, len, flags);
if (ret < 0 && errno == EINTR)
goto again;
return ret;
}
ssize_t lxc_read_nointr_expect(int fd, void *buf, size_t count, const void *expected_buf) ssize_t lxc_read_nointr_expect(int fd, void *buf, size_t count, const void *expected_buf)
{ {
ssize_t ret; ssize_t ret;

View File

@ -37,9 +37,12 @@ extern int lxc_read_from_file(const char *filename, void *buf, size_t count);
/* send and receive buffers completely */ /* send and receive buffers completely */
extern ssize_t lxc_write_nointr(int fd, const void *buf, size_t count); extern ssize_t lxc_write_nointr(int fd, const void *buf, size_t count);
extern ssize_t lxc_send_nointr(int sockfd, void *buf, size_t len, int flags);
extern ssize_t lxc_read_nointr(int fd, void *buf, size_t count); extern ssize_t lxc_read_nointr(int fd, void *buf, size_t count);
extern ssize_t lxc_read_nointr_expect(int fd, void *buf, size_t count, extern ssize_t lxc_read_nointr_expect(int fd, void *buf, size_t count,
const void *expected_buf); const void *expected_buf);
extern ssize_t lxc_recv_nointr(int sockfd, void *buf, size_t len, int flags);
extern bool file_exists(const char *f); extern bool file_exists(const char *f);
extern int print_to_file(const char *file, const char *content); extern int print_to_file(const char *file, const char *content);
extern int is_dir(const char *path); extern int is_dir(const char *path);

View File

@ -311,7 +311,7 @@ static int log_append_logfile(const struct lxc_log_appender *appender,
return 0; return 0;
if (lxc_unix_epoch_to_utc(date_time, LXC_LOG_TIME_SIZE, &event->timestamp) < 0) if (lxc_unix_epoch_to_utc(date_time, LXC_LOG_TIME_SIZE, &event->timestamp) < 0)
return 0; return -1;
n = snprintf(buffer, sizeof(buffer), n = snprintf(buffer, sizeof(buffer),
"%s%s%s %s %-8s %s - %s:%s:%d - ", "%s%s%s %s %-8s %s - %s:%s:%d - ",

View File

@ -276,6 +276,7 @@ ATTR_UNUSED static inline void LXC_##LEVEL(struct lxc_log_locinfo* locinfo, \
{ \ { \
if (lxc_log_priority_is_enabled(acategory, LXC_LOG_LEVEL_##LEVEL)) { \ if (lxc_log_priority_is_enabled(acategory, LXC_LOG_LEVEL_##LEVEL)) { \
va_list va_ref; \ va_list va_ref; \
int saved_errno; \
struct lxc_log_event evt = { \ struct lxc_log_event evt = { \
.category = (acategory)->name, \ .category = (acategory)->name, \
.priority = LXC_LOG_LEVEL_##LEVEL, \ .priority = LXC_LOG_LEVEL_##LEVEL, \
@ -287,12 +288,14 @@ ATTR_UNUSED static inline void LXC_##LEVEL(struct lxc_log_locinfo* locinfo, \
* without restrictions. So let's use it for our \ * without restrictions. So let's use it for our \
* logging stamps. \ * logging stamps. \
*/ \ */ \
saved_errno = errno; \
(void)clock_gettime(CLOCK_REALTIME, &evt.timestamp); \ (void)clock_gettime(CLOCK_REALTIME, &evt.timestamp); \
\ \
va_start(va_ref, format); \ va_start(va_ref, format); \
evt.vap = &va_ref; \ evt.vap = &va_ref; \
__lxc_log(acategory, &evt); \ __lxc_log(acategory, &evt); \
va_end(va_ref); \ va_end(va_ref); \
errno = saved_errno; \
} \ } \
} }
@ -341,7 +344,9 @@ ATTR_UNUSED static inline void LXC_##LEVEL(struct lxc_log_locinfo* locinfo, \
char errno_buf[MAXPATHLEN / 2] = {"Failed to get errno string"}; \ char errno_buf[MAXPATHLEN / 2] = {"Failed to get errno string"}; \
char *ptr = NULL; \ char *ptr = NULL; \
{ \ { \
int saved_errno = errno; \
ptr = strerror_r(errno, errno_buf, sizeof(errno_buf)); \ ptr = strerror_r(errno, errno_buf, sizeof(errno_buf)); \
errno = saved_errno; \
if (!ptr) \ if (!ptr) \
ptr = errno_buf; \ ptr = errno_buf; \
} }
@ -350,7 +355,9 @@ ATTR_UNUSED static inline void LXC_##LEVEL(struct lxc_log_locinfo* locinfo, \
char errno_buf[MAXPATHLEN / 2] = {"Failed to get errno string"}; \ char errno_buf[MAXPATHLEN / 2] = {"Failed to get errno string"}; \
char *ptr = errno_buf; \ char *ptr = errno_buf; \
{ \ { \
int saved_errno = errno; \
(void)strerror_r(errno, errno_buf, sizeof(errno_buf)); \ (void)strerror_r(errno, errno_buf, sizeof(errno_buf)); \
errno = saved_errno; \
} }
#endif #endif
#elif ENFORCE_THREAD_SAFETY #elif ENFORCE_THREAD_SAFETY

View File

@ -48,6 +48,7 @@
#include "af_unix.h" #include "af_unix.h"
#include "conf.h" #include "conf.h"
#include "config.h" #include "config.h"
#include "file_utils.h"
#include "log.h" #include "log.h"
#include "macro.h" #include "macro.h"
#include "network.h" #include "network.h"
@ -3056,7 +3057,7 @@ int lxc_network_send_veth_names_to_child(struct lxc_handler *handler)
if (netdev->type != LXC_NET_VETH) if (netdev->type != LXC_NET_VETH)
continue; continue;
ret = send(data_sock, netdev->name, IFNAMSIZ, MSG_NOSIGNAL); ret = lxc_send_nointr(data_sock, netdev->name, IFNAMSIZ, MSG_NOSIGNAL);
if (ret < 0) if (ret < 0)
return -1; return -1;
TRACE("Sent network device name \"%s\" to child", netdev->name); TRACE("Sent network device name \"%s\" to child", netdev->name);
@ -3081,7 +3082,7 @@ int lxc_network_recv_veth_names_from_parent(struct lxc_handler *handler)
if (netdev->type != LXC_NET_VETH) if (netdev->type != LXC_NET_VETH)
continue; continue;
ret = recv(data_sock, netdev->name, IFNAMSIZ, 0); ret = lxc_recv_nointr(data_sock, netdev->name, IFNAMSIZ, 0);
if (ret < 0) if (ret < 0)
return -1; return -1;
TRACE("Received network device name \"%s\" from parent", netdev->name); TRACE("Received network device name \"%s\" from parent", netdev->name);
@ -3104,14 +3105,14 @@ int lxc_network_send_name_and_ifindex_to_parent(struct lxc_handler *handler)
struct lxc_netdev *netdev = iterator->elem; struct lxc_netdev *netdev = iterator->elem;
/* Send network device name in the child's namespace to parent. */ /* Send network device name in the child's namespace to parent. */
ret = send(data_sock, netdev->name, IFNAMSIZ, MSG_NOSIGNAL); ret = lxc_send_nointr(data_sock, netdev->name, IFNAMSIZ, MSG_NOSIGNAL);
if (ret < 0) if (ret < 0)
return -1; return -1;
/* Send network device ifindex in the child's namespace to /* Send network device ifindex in the child's namespace to
* parent. * parent.
*/ */
ret = send(data_sock, &netdev->ifindex, sizeof(netdev->ifindex), MSG_NOSIGNAL); ret = lxc_send_nointr(data_sock, &netdev->ifindex, sizeof(netdev->ifindex), MSG_NOSIGNAL);
if (ret < 0) if (ret < 0)
return -1; return -1;
} }
@ -3136,14 +3137,14 @@ int lxc_network_recv_name_and_ifindex_from_child(struct lxc_handler *handler)
/* Receive network device name in the child's namespace to /* Receive network device name in the child's namespace to
* parent. * parent.
*/ */
ret = recv(data_sock, netdev->name, IFNAMSIZ, 0); ret = lxc_recv_nointr(data_sock, netdev->name, IFNAMSIZ, 0);
if (ret < 0) if (ret < 0)
return -1; return -1;
/* Receive network device ifindex in the child's namespace to /* Receive network device ifindex in the child's namespace to
* parent. * parent.
*/ */
ret = recv(data_sock, &netdev->ifindex, sizeof(netdev->ifindex), 0); ret = lxc_recv_nointr(data_sock, &netdev->ifindex, sizeof(netdev->ifindex), 0);
if (ret < 0) if (ret < 0)
return -1; return -1;
} }
@ -3202,6 +3203,7 @@ int lxc_netns_set_nsid(int fd)
struct nl_handler nlh; struct nl_handler nlh;
struct nlmsghdr *hdr; struct nlmsghdr *hdr;
struct rtgenmsg *msg; struct rtgenmsg *msg;
int saved_errno;
__s32 ns_id = -1; __s32 ns_id = -1;
__u32 netns_fd = fd; __u32 netns_fd = fd;
@ -3224,7 +3226,9 @@ int lxc_netns_set_nsid(int fd)
addattr(hdr, 1024, __LXC_NETNSA_NSID, &ns_id, sizeof(ns_id)); addattr(hdr, 1024, __LXC_NETNSA_NSID, &ns_id, sizeof(ns_id));
ret = __netlink_transaction(&nlh, hdr, hdr); ret = __netlink_transaction(&nlh, hdr, hdr);
saved_errno = errno;
netlink_close(&nlh); netlink_close(&nlh);
errno = saved_errno;
if (ret < 0) if (ret < 0)
return -1; return -1;

View File

@ -20,6 +20,9 @@
* License along with this library; if not, write to the Free Software * License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/ */
#include "config.h"
#include <sys/socket.h> #include <sys/socket.h>
#include <string.h> #include <string.h>
#include <stdio.h> #include <stdio.h>
@ -30,8 +33,11 @@
#include <linux/netlink.h> #include <linux/netlink.h>
#include <linux/rtnetlink.h> #include <linux/rtnetlink.h>
#include "log.h"
#include "nl.h" #include "nl.h"
lxc_log_define(nl, lxc);
extern size_t nlmsg_len(const struct nlmsg *nlmsg) extern size_t nlmsg_len(const struct nlmsg *nlmsg)
{ {
return nlmsg->nlmsghdr->nlmsg_len - NLMSG_HDRLEN; return nlmsg->nlmsghdr->nlmsg_len - NLMSG_HDRLEN;
@ -201,8 +207,10 @@ again:
if (!ret) if (!ret)
return 0; return 0;
if (msg.msg_flags & MSG_TRUNC && (ret == nlmsghdr->nlmsg_len)) if (msg.msg_flags & MSG_TRUNC && (ret == nlmsghdr->nlmsg_len)) {
return -EMSGSIZE; errno = EMSGSIZE;
ret = -1;
}
return ret; return ret;
} }
@ -252,18 +260,21 @@ extern int __netlink_transaction(struct nl_handler *handler,
ret = __netlink_send(handler, request); ret = __netlink_send(handler, request);
if (ret < 0) if (ret < 0)
return ret; return -1;
ret = __netlink_recv(handler, answer); ret = __netlink_recv(handler, answer);
if (ret < 0) if (ret < 0)
return ret; return -1;
ret = 0;
if (answer->nlmsg_type == NLMSG_ERROR) { if (answer->nlmsg_type == NLMSG_ERROR) {
struct nlmsgerr *err = (struct nlmsgerr *)NLMSG_DATA(answer); struct nlmsgerr *err = (struct nlmsgerr *)NLMSG_DATA(answer);
return err->error; errno = -err->error;
if (err->error < 0)
ret = -1;
} }
return 0; return ret;
} }
extern int netlink_transaction(struct nl_handler *handler, extern int netlink_transaction(struct nl_handler *handler,

View File

@ -61,6 +61,7 @@
#include "conf.h" #include "conf.h"
#include "confile_utils.h" #include "confile_utils.h"
#include "error.h" #include "error.h"
#include "file_utils.h"
#include "list.h" #include "list.h"
#include "lsm/lsm.h" #include "lsm/lsm.h"
#include "log.h" #include "log.h"
@ -440,16 +441,9 @@ int lxc_serve_state_clients(const char *name, struct lxc_handler *handler,
TRACE("Sending state %s to state client %d", TRACE("Sending state %s to state client %d",
lxc_state2str(state), client->clientfd); lxc_state2str(state), client->clientfd);
again: ret = lxc_send_nointr(client->clientfd, &msg, sizeof(msg), MSG_NOSIGNAL);
ret = send(client->clientfd, &msg, sizeof(msg), MSG_NOSIGNAL); if (ret <= 0)
if (ret <= 0) {
if (errno == EINTR) {
TRACE("Caught EINTR; retrying");
goto again;
}
SYSERROR("Failed to send message to client"); SYSERROR("Failed to send message to client");
}
/* kick client from list */ /* kick client from list */
lxc_list_del(cur); lxc_list_del(cur);
@ -1795,13 +1789,11 @@ static int lxc_spawn(struct lxc_handler *handler)
DEBUG("Preserved net namespace via fd %d", ret); DEBUG("Preserved net namespace via fd %d", ret);
ret = lxc_netns_set_nsid(handler->nsfd[LXC_NS_NET]); ret = lxc_netns_set_nsid(handler->nsfd[LXC_NS_NET]);
if (ret < 0) { if (ret < 0)
errno = -ret;
SYSERROR("Failed to allocate new network namespace id"); SYSERROR("Failed to allocate new network namespace id");
} else { else
TRACE("Allocated new network namespace id"); TRACE("Allocated new network namespace id");
} }
}
/* Create the network configuration. */ /* Create the network configuration. */
if (handler->ns_clone_flags & CLONE_NEWNET) { if (handler->ns_clone_flags & CLONE_NEWNET) {