mirror of
https://gitlab.isc.org/isc-projects/bind9
synced 2025-09-01 15:05:23 +00:00
2489. [port] solaris: Workaround Solaris's kernel bug about
/dev/poll: http://bugs.opensolaris.org/view_bug.do?bug_id=6724237 Define ISC_SOCKET_USE_POLLWATCH at build time to enable this workaround. [RT #18870]
This commit is contained in:
6
CHANGES
6
CHANGES
@@ -1,3 +1,9 @@
|
|||||||
|
2489. [port] solaris: Workaround Solaris's kernel bug about
|
||||||
|
/dev/poll:
|
||||||
|
http://bugs.opensolaris.org/view_bug.do?bug_id=6724237
|
||||||
|
Define ISC_SOCKET_USE_POLLWATCH at build time to enable
|
||||||
|
this workaround. [RT #18870]
|
||||||
|
|
||||||
2488. [func] Added a tool, dnssec-dsfromkey, to generate DS records
|
2488. [func] Added a tool, dnssec-dsfromkey, to generate DS records
|
||||||
from keyset and .key files. [RT #18694]
|
from keyset and .key files. [RT #18694]
|
||||||
|
|
||||||
|
4
README
4
README
@@ -457,6 +457,10 @@ Building
|
|||||||
To create the default pid files in ${localstatedir}/run rather
|
To create the default pid files in ${localstatedir}/run rather
|
||||||
than ${localstatedir}/run/{named,lwresd}/ set.
|
than ${localstatedir}/run/{named,lwresd}/ set.
|
||||||
-DNS_RUN_PID_DIR=0
|
-DNS_RUN_PID_DIR=0
|
||||||
|
Enabling workaround for Solaris kernel bug about /dev/poll
|
||||||
|
-DISC_SOCKET_USE_POLLWATCH=1
|
||||||
|
The watch timeout is also configurable, e.g.,
|
||||||
|
-DISC_SOCKET_POLLWATCH_TIMEOUT=20
|
||||||
|
|
||||||
LDFLAGS
|
LDFLAGS
|
||||||
Linker flags. Defaults to empty string.
|
Linker flags. Defaults to empty string.
|
||||||
|
@@ -15,7 +15,7 @@
|
|||||||
* PERFORMANCE OF THIS SOFTWARE.
|
* PERFORMANCE OF THIS SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* $Id: socket.c,v 1.304 2008/10/17 21:49:23 jinmei Exp $ */
|
/* $Id: socket.c,v 1.305 2008/11/08 22:35:12 jinmei Exp $ */
|
||||||
|
|
||||||
/*! \file */
|
/*! \file */
|
||||||
|
|
||||||
@@ -148,6 +148,35 @@ struct isc_socketwait {
|
|||||||
#endif /* __APPLE__ */
|
#endif /* __APPLE__ */
|
||||||
#endif /* USE_SELECT */
|
#endif /* USE_SELECT */
|
||||||
|
|
||||||
|
#ifdef ISC_SOCKET_USE_POLLWATCH
|
||||||
|
/*%
|
||||||
|
* If this macro is defined, enable workaround for a Solaris /dev/poll kernel
|
||||||
|
* bug: DP_POLL ioctl could keep sleeping even if socket I/O is possible for
|
||||||
|
* some of the specified FD. The idea is based on the observation that it's
|
||||||
|
* likely for a busy server to keep receiving packets. It specifically works
|
||||||
|
* as follows: the socket watcher is first initialized with the state of
|
||||||
|
* "poll_idle". While it's in the idle state it keeps sleeping until a socket
|
||||||
|
* event occurs. When it wakes up for a socket I/O event, it moves to the
|
||||||
|
* poll_active state, and sets the poll timeout to a short period
|
||||||
|
* (ISC_SOCKET_POLLWATCH_TIMEOUT msec). If timeout occurs in this state, the
|
||||||
|
* watcher goes to the poll_checking state with the same timeout period.
|
||||||
|
* In this state, the watcher tries to detect whether this is a break
|
||||||
|
* during intermittent events or the kernel bug is triggered. If the next
|
||||||
|
* polling reports an event within the short period, the previous timeout is
|
||||||
|
* likely to be a kernel bug, and so the watcher goes back to the active state.
|
||||||
|
* Otherwise, it moves to the idle state again.
|
||||||
|
*
|
||||||
|
* It's not clear whether this is a thread-related bug, but since we've only
|
||||||
|
* seen this with threads, this workaround is used only when enabling threads.
|
||||||
|
*/
|
||||||
|
|
||||||
|
typedef enum { poll_idle, poll_active, poll_checking } pollstate_t;
|
||||||
|
|
||||||
|
#ifndef ISC_SOCKET_POLLWATCH_TIMEOUT
|
||||||
|
#define ISC_SOCKET_POLLWATCH_TIMEOUT 10
|
||||||
|
#endif /* ISC_SOCKET_POLLWATCH_TIMEOUT */
|
||||||
|
#endif /* ISC_SOCKET_USE_POLLWATCH */
|
||||||
|
|
||||||
/*%
|
/*%
|
||||||
* Size of per-FD lock buckets.
|
* Size of per-FD lock buckets.
|
||||||
*/
|
*/
|
||||||
@@ -3230,6 +3259,9 @@ watcher(void *uap) {
|
|||||||
int maxfd;
|
int maxfd;
|
||||||
#endif
|
#endif
|
||||||
char strbuf[ISC_STRERRORSIZE];
|
char strbuf[ISC_STRERRORSIZE];
|
||||||
|
#ifdef ISC_SOCKET_USE_POLLWATCH
|
||||||
|
pollstate_t pollstate = poll_idle;
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Get the control fd here. This will never change.
|
* Get the control fd here. This will never change.
|
||||||
@@ -3247,7 +3279,14 @@ watcher(void *uap) {
|
|||||||
#elif defined(USE_DEVPOLL)
|
#elif defined(USE_DEVPOLL)
|
||||||
dvp.dp_fds = manager->events;
|
dvp.dp_fds = manager->events;
|
||||||
dvp.dp_nfds = manager->nevents;
|
dvp.dp_nfds = manager->nevents;
|
||||||
|
#ifndef ISC_SOCKET_USE_POLLWATCH
|
||||||
dvp.dp_timeout = -1;
|
dvp.dp_timeout = -1;
|
||||||
|
#else
|
||||||
|
if (pollstate == poll_idle)
|
||||||
|
dvp.dp_timeout = -1;
|
||||||
|
else
|
||||||
|
dvp.dp_timeout = ISC_SOCKET_POLLWATCH_TIMEOUT;
|
||||||
|
#endif /* ISC_SOCKET_USE_POLLWATCH */
|
||||||
cc = ioctl(manager->devpoll_fd, DP_POLL, &dvp);
|
cc = ioctl(manager->devpoll_fd, DP_POLL, &dvp);
|
||||||
#elif defined(USE_SELECT)
|
#elif defined(USE_SELECT)
|
||||||
LOCK(&manager->lock);
|
LOCK(&manager->lock);
|
||||||
@@ -3271,6 +3310,33 @@ watcher(void *uap) {
|
|||||||
ISC_MSG_FAILED,
|
ISC_MSG_FAILED,
|
||||||
"failed"), strbuf);
|
"failed"), strbuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(USE_DEVPOLL) && defined(ISC_SOCKET_USE_POLLWATCH)
|
||||||
|
if (cc == 0) {
|
||||||
|
if (pollstate == poll_active)
|
||||||
|
pollstate = poll_checking;
|
||||||
|
else if (pollstate == poll_checking)
|
||||||
|
pollstate = poll_idle;
|
||||||
|
} else if (cc > 0) {
|
||||||
|
if (pollstate == poll_checking) {
|
||||||
|
/*
|
||||||
|
* XXX: We'd like to use a more
|
||||||
|
* verbose log level as it's actually an
|
||||||
|
* unexpected event, but the kernel bug
|
||||||
|
* reportedly happens pretty frequently
|
||||||
|
* (and it can also be a false positive)
|
||||||
|
* so it would be just too noisy.
|
||||||
|
*/
|
||||||
|
manager_log(manager,
|
||||||
|
ISC_LOGCATEGORY_GENERAL,
|
||||||
|
ISC_LOGMODULE_SOCKET,
|
||||||
|
ISC_LOG_DEBUG(1),
|
||||||
|
ISC_LOG_INFO,
|
||||||
|
"unexpected POLL timeout");
|
||||||
|
}
|
||||||
|
pollstate = poll_active;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
} while (cc < 0);
|
} while (cc < 0);
|
||||||
|
|
||||||
#if defined(USE_KQUEUE) || defined (USE_EPOLL) || defined (USE_DEVPOLL)
|
#if defined(USE_KQUEUE) || defined (USE_EPOLL) || defined (USE_DEVPOLL)
|
||||||
|
Reference in New Issue
Block a user