diff --git a/CHANGES b/CHANGES index 537258fdaf..dee51f11df 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,7 @@ +2398. [bug] Improve file descriptor management. New, + temporary, named.conf option reserved-sockets, + default 512. [RT #18344] + 2397. [bug] gssapi_functions had too many elements. [RT #18355] 2396. [bug] Don't set SO_REUSEADDR for randomized ports. diff --git a/bin/named/config.c b/bin/named/config.c index a1df818dcd..38075ff962 100644 --- a/bin/named/config.c +++ b/bin/named/config.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: config.c,v 1.82.38.5.2.1 2008/07/23 11:11:41 marka Exp $ */ +/* $Id: config.c,v 1.82.38.5.2.2 2008/07/23 11:46:01 marka Exp $ */ /*! \file */ @@ -100,6 +100,7 @@ options {\n\ edns-udp-size 4096;\n\ max-udp-size 4096;\n\ request-nsid false;\n\ + reserved-sockets 512;\n\ \n\ /* view */\n\ allow-notify {none;};\n\ diff --git a/bin/named/named.conf.docbook b/bin/named/named.conf.docbook index 6b6db6d0e1..986db567be 100644 --- a/bin/named/named.conf.docbook +++ b/bin/named/named.conf.docbook @@ -17,7 +17,7 @@ - PERFORMANCE OF THIS SOFTWARE. --> - + Aug 13, 2004 @@ -201,6 +201,7 @@ options { port integer; querylog boolean; recursing-file quoted_string; + reserved-sockets integer; random-device quoted_string; recursive-clients integer; serial-query-rate integer; diff --git a/bin/named/server.c b/bin/named/server.c index d7013825ea..beb5c5e8ef 100644 --- a/bin/named/server.c +++ b/bin/named/server.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: server.c,v 1.495.10.11 2008/05/27 22:36:09 each Exp $ */ +/* $Id: server.c,v 1.495.10.11.2.1 2008/07/23 11:46:01 marka Exp $ */ /*! \file */ @@ -2866,27 +2866,29 @@ static isc_result_t load_configuration(const char *filename, ns_server_t *server, isc_boolean_t first_time) { - isc_result_t result; - isc_interval_t interval; - cfg_parser_t *parser = NULL; + cfg_aclconfctx_t aclconfctx; cfg_obj_t *config; - const cfg_obj_t *options; - const cfg_obj_t *views; - const cfg_obj_t *obj; - const cfg_obj_t *v4ports, *v6ports; - const cfg_obj_t *maps[3]; - const cfg_obj_t *builtin_views; + cfg_parser_t *parser = NULL; const cfg_listelt_t *element; + const cfg_obj_t *builtin_views; + const cfg_obj_t *maps[3]; + const cfg_obj_t *obj; + const cfg_obj_t *options; + const cfg_obj_t *v4ports, *v6ports; + const cfg_obj_t *views; dns_view_t *view = NULL; dns_view_t *view_next; - dns_viewlist_t viewlist; dns_viewlist_t tmpviewlist; - cfg_aclconfctx_t aclconfctx; - isc_uint32_t interface_interval; - isc_uint32_t heartbeat_interval; - isc_uint32_t udpsize; + dns_viewlist_t viewlist; in_port_t listen_port; int i; + isc_interval_t interval; + isc_resourcevalue_t files; + isc_result_t result; + isc_uint32_t heartbeat_interval; + isc_uint32_t interface_interval; + isc_uint32_t reserved; + isc_uint32_t udpsize; cfg_aclconfctx_init(&aclconfctx); ISC_LIST_INIT(viewlist); @@ -2975,6 +2977,43 @@ load_configuration(const char *filename, ns_server_t *server, */ set_limits(maps); + /* + * Sanity check on "files" limit. + */ + result = isc_resource_curlimit(isc_resource_openfiles, &files); + if (result == ISC_R_SUCCESS && files < FD_SETSIZE) { + isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, + NS_LOGMODULE_SERVER, ISC_LOG_WARNING, + "the 'files' limit (%" ISC_PRINT_QUADFORMAT "u) " + "is less than FD_SETSIZE (%d), increase " + "'files' in named.conf or recompile with a " + "smaller FD_SETSIZE.", files, FD_SETSIZE); + if (files > FD_SETSIZE) + files = FD_SETSIZE; + } else + files = FD_SETSIZE; + + /* + * Set the number of socket reserved for TCP, stdio etc. + */ + obj = NULL; + result = ns_config_get(maps, "reserved-sockets", &obj); + INSIST(result == ISC_R_SUCCESS); + reserved = cfg_obj_asuint32(obj); + if (files < 128U) /* Prevent underflow. */ + reserved = 0; + else if (reserved > files - 128U) /* Mimimum UDP space. */ + reserved = files - 128; + if (reserved < 128U) /* Mimimum TCP/stdio space. */ + reserved = 128; + if (reserved + 128U > files) { + isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, + NS_LOGMODULE_SERVER, ISC_LOG_WARNING, + "less than 128 UDP sockets available after " + "applying 'reserved-sockets' and 'files'"); + } + isc__socketmgr_setreserved(ns_g_socketmgr, reserved); + /* * Configure various server options. */ diff --git a/doc/arm/Bv9ARM-book.xml b/doc/arm/Bv9ARM-book.xml index 0e31c0ba99..7401b6475c 100644 --- a/doc/arm/Bv9ARM-book.xml +++ b/doc/arm/Bv9ARM-book.xml @@ -18,7 +18,7 @@ - PERFORMANCE OF THIS SOFTWARE. --> - + BIND 9 Administrator Reference Manual @@ -4512,6 +4512,7 @@ category notify { null; }; max-transfer-idle-in number; max-transfer-idle-out number; tcp-clients number; + reserved-sockets number; recursive-clients number; serial-query-rate number; serial-queries number; @@ -6813,6 +6814,23 @@ query-source-v6 address * port *; + + reserved-sockets + + + The number of file descriptors reserved for TCP, stdio, + etc. This needs to be big enough to cover the number of + interfaces named listens on, tcp-clients as well as + to provide room for outgoing TCP queries and incoming zone + transfers. The default is 512. + The minimum value is 128 and the + maximum value is 128 less than + 'files' or FD_SETSIZE (whichever is smaller). This + option may be removed in the future. + + + + max-cache-size diff --git a/lib/isc/include/isc/resource.h b/lib/isc/include/isc/resource.h index 7a615655f8..3e7606c2f0 100644 --- a/lib/isc/include/isc/resource.h +++ b/lib/isc/include/isc/resource.h @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: resource.h,v 1.11 2007/06/19 23:47:18 tbox Exp $ */ +/* $Id: resource.h,v 1.11.232.1 2008/07/23 11:46:02 marka Exp $ */ #ifndef ISC_RESOURCE_H #define ISC_RESOURCE_H 1 @@ -81,6 +81,19 @@ isc_resource_getlimit(isc_resource_t resource, isc_resourcevalue_t *value); *\li #ISC_R_NOTIMPLEMENTED 'resource' is not a type known by the OS. */ +isc_result_t +isc_resource_curlimit(isc_resource_t resource, isc_resourcevalue_t *value); +/* + * Get the current limit on a resource. + * + * Requires: + * 'resource' is a valid member of the isc_resource_t enumeration. + * + * Returns: + * ISC_R_SUCCESS Success. + * ISC_R_NOTIMPLEMENTED 'resource' is not a type known by the OS. + */ + ISC_LANG_ENDDECLS #endif /* ISC_RESOURCE_H */ diff --git a/lib/isc/include/isc/socket.h b/lib/isc/include/isc/socket.h index 5464f0a472..23bb66345a 100644 --- a/lib/isc/include/isc/socket.h +++ b/lib/isc/include/isc/socket.h @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: socket.h,v 1.72.226.2 2008/07/23 07:32:56 tbox Exp $ */ +/* $Id: socket.h,v 1.72.226.3 2008/07/23 11:46:02 marka Exp $ */ #ifndef ISC_SOCKET_H #define ISC_SOCKET_H 1 @@ -823,6 +823,12 @@ isc_socketmgr_renderxml(isc_socketmgr_t *mgr, xmlTextWriterPtr writer); * Render internal statistics and other state into the XML document. */ +void +isc__socketmgr_setreserved(isc_socketmgr_t *mgr, isc_uint32_t); +/*%< + * Temporary. For use by named only. + */ + #endif /* HAVE_LIBXML2 */ ISC_LANG_ENDDECLS diff --git a/lib/isc/unix/resource.c b/lib/isc/unix/resource.c index 243ca20176..33a7f81321 100644 --- a/lib/isc/unix/resource.c +++ b/lib/isc/unix/resource.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: resource.c,v 1.14.128.3.12.1 2008/07/23 11:34:17 marka Exp $ */ +/* $Id: resource.c,v 1.14.128.3.12.2 2008/07/23 11:46:02 marka Exp $ */ #include @@ -186,3 +186,20 @@ isc_resource_getlimit(isc_resource_t resource, isc_resourcevalue_t *value) { return (result); } + +isc_result_t +isc_resource_curlimit(isc_resource_t resource, isc_resourcevalue_t *value) { + int unixresult; + int unixresource; + struct rlimit rl; + isc_result_t result; + + result = resource2rlim(resource, &unixresource); + if (result == ISC_R_SUCCESS) { + unixresult = getrlimit(unixresource, &rl); + INSIST(unixresult == 0); + *value = rl.rlim_cur; + } + + return (result); +} diff --git a/lib/isc/unix/socket.c b/lib/isc/unix/socket.c index bda236a13b..8874a70ecc 100644 --- a/lib/isc/unix/socket.c +++ b/lib/isc/unix/socket.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: socket.c,v 1.275.10.4.4.1 2008/07/22 04:03:53 marka Exp $ */ +/* $Id: socket.c,v 1.275.10.4.4.2 2008/07/23 11:46:02 marka Exp $ */ /*! \file */ @@ -216,6 +216,7 @@ struct isc_socketmgr { isc_socket_t *fds[FD_SETSIZE]; int fdstate[FD_SETSIZE]; int maxfd; + int reserved; /* unlocked */ #ifdef ISC_PLATFORM_USETHREADS isc_thread_t watcher; isc_condition_t shutdown_ok; @@ -1496,9 +1497,18 @@ isc_socket_create(isc_socketmgr_t *manager, int pf, isc_sockettype_t type, #ifdef F_DUPFD /* - * Leave a space for stdio to work in. + * Leave a space for stdio and TCP to work in. */ - if (sock->fd >= 0 && sock->fd < 20) { + if (manager->reserved != 0 && type == isc_sockettype_udp && + sock->fd >= 0 && sock->fd < manager->reserved) { + int new, tmp; + new = fcntl(sock->fd, F_DUPFD, manager->reserved); + tmp = errno; + (void)close(sock->fd); + errno = tmp; + sock->fd = new; + err = "isc_socket_create: fcntl/reserved"; + } else if (sock->fd >= 0 && sock->fd < 20) { int new, tmp; new = fcntl(sock->fd, F_DUPFD, 20); tmp = errno; @@ -2598,6 +2608,14 @@ watcher(void *uap) { } #endif /* ISC_PLATFORM_USETHREADS */ +void +isc__socketmgr_setreserved(isc_socketmgr_t *manager, isc_uint32_t reserved) { + + REQUIRE(VALID_MANAGER(manager)); + + manager->reserved = reserved; +} + /* * Create a new socket manager. */ @@ -2679,6 +2697,7 @@ isc_socketmgr_create(isc_mem_t *mctx, isc_socketmgr_t **managerp) { #else /* ISC_PLATFORM_USETHREADS */ manager->maxfd = 0; #endif /* ISC_PLATFORM_USETHREADS */ + manager->reserved = 0; memset(manager->fdstate, 0, sizeof(manager->fdstate)); #ifdef ISC_PLATFORM_USETHREADS diff --git a/lib/isc/win32/libisc.def b/lib/isc/win32/libisc.def index dda07ebf42..820eafd259 100644 --- a/lib/isc/win32/libisc.def +++ b/lib/isc/win32/libisc.def @@ -34,6 +34,7 @@ isc__mem_putanddetach isc__mem_strdup isc__mempool_get isc__mempool_put +isc__socketmgr_setminudp isc__strerror isc_app_block isc_app_finish diff --git a/lib/isc/win32/resource.c b/lib/isc/win32/resource.c index 328b711ca6..e4ff66d9b3 100644 --- a/lib/isc/win32/resource.c +++ b/lib/isc/win32/resource.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: resource.c,v 1.8 2007/06/19 23:47:19 tbox Exp $ */ +/* $Id: resource.c,v 1.8.232.1 2008/07/23 11:46:02 marka Exp $ */ #include @@ -65,3 +65,13 @@ isc_resource_getlimit(isc_resource_t resource, isc_resourcevalue_t *value) { *value = WIN32_MAX_OPEN_FILES; return (ISC_R_SUCCESS); } + +isc_result_t +isc_resource_curlimit(isc_resource_t resource, isc_resourcevalue_t *value) { + + if (resource != isc_resource_openfiles) + return (ISC_R_NOTIMPLEMENTED); + + *value = WIN32_MAX_OPEN_FILES; + return (ISC_R_SUCCESS); +} diff --git a/lib/isc/win32/socket.c b/lib/isc/win32/socket.c index 3207797a78..d96f2b6141 100644 --- a/lib/isc/win32/socket.c +++ b/lib/isc/win32/socket.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: socket.c,v 1.52.94.2.4.1 2008/07/22 04:03:54 marka Exp $ */ +/* $Id: socket.c,v 1.52.94.2.4.2 2008/07/23 11:46:02 marka Exp $ */ /* This code has been rewritten to take advantage of Windows Sockets * I/O Completion Ports and Events. I/O Completion Ports is ONLY @@ -3877,3 +3877,9 @@ void * isc_socket_gettag(isc_socket_t *socket) { return (socket->tag); } + +void +isc__socketmgr_setreserved(isc_socketmgr_t *manager, isc_uint32_t reserved) { + UNUSED(manager); + UNUSED(reserved); +} diff --git a/lib/isccfg/namedconf.c b/lib/isccfg/namedconf.c index 21ab77ad7c..cdf9777a6b 100644 --- a/lib/isccfg/namedconf.c +++ b/lib/isccfg/namedconf.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: namedconf.c,v 1.78.46.7 2008/05/27 22:36:11 each Exp $ */ +/* $Id: namedconf.c,v 1.78.46.7.2.1 2008/07/23 11:46:02 marka Exp $ */ /*! \file */ @@ -639,6 +639,7 @@ options_clauses[] = { { "recursing-file", &cfg_type_qstring, 0 }, { "random-device", &cfg_type_qstring, 0 }, { "recursive-clients", &cfg_type_uint32, 0 }, + { "reserved-sockets", &cfg_type_uint32, 0 }, { "serial-queries", &cfg_type_uint32, CFG_CLAUSEFLAG_OBSOLETE }, { "serial-query-rate", &cfg_type_uint32, 0 }, { "server-id", &cfg_type_serverid, 0 },