mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-01-11 23:37:42 +00:00
lxc_controller.c: don't ignore failed "accept"
* src/lxc/lxc_controller.c (ignorable_epoll_accept_errno): New function. (lxcControllerMain): Handle a failed accept carefully: most errno values indicate legitimate failure and must be fatal. However, ignore a special case: that in which an incoming client quits between the poll() indicating its presence, and our accept() which is trying to process it.
This commit is contained in:
parent
348c6fc0ab
commit
1f6fc519cd
@ -269,6 +269,17 @@ typedef struct _lxcTtyForwardFd_t {
|
||||
int active;
|
||||
} lxcTtyForwardFd_t;
|
||||
|
||||
/* Return true if it is ok to ignore an accept-after-epoll syscall
|
||||
that fails with the specified errno value. Else false. */
|
||||
static bool
|
||||
ignorable_epoll_accept_errno(int errnum)
|
||||
{
|
||||
return (errnum == EINVAL
|
||||
|| errnum == ECONNABORTED
|
||||
|| errnum == EAGAIN
|
||||
|| errnum == EWOULDBLOCK);
|
||||
}
|
||||
|
||||
/**
|
||||
* lxcControllerMain
|
||||
* @monitor: server socket fd to accept client requests
|
||||
@ -350,6 +361,18 @@ static int lxcControllerMain(int monitor,
|
||||
if (numEvents > 0) {
|
||||
if (epollEvent.data.fd == monitor) {
|
||||
int fd = accept(monitor, NULL, 0);
|
||||
if (fd < 0) {
|
||||
/* First reflex may be simply to declare accept failure
|
||||
to be a fatal error. However, accept may fail when
|
||||
a client quits between the above epoll_wait and here.
|
||||
That case is not fatal, but rather to be expected,
|
||||
if not common, so ignore it. */
|
||||
if (ignorable_epoll_accept_errno(errno))
|
||||
continue;
|
||||
virReportSystemError(errno, "%s",
|
||||
_("accept(monitor,...) failed"));
|
||||
goto cleanup;
|
||||
}
|
||||
if (client != -1) { /* Already connected, so kick new one out */
|
||||
close(fd);
|
||||
continue;
|
||||
|
Loading…
x
Reference in New Issue
Block a user