diff --git a/CHANGES b/CHANGES index 1dbce9198e..b948a639a1 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,6 @@ +2386. [bug] Add warning about too small 'open files' limit + [RT #18269]. + 2385. [bug] A condition variable in socket.c could leak in rare error handling [RT #17968]. diff --git a/bin/named/server.c b/bin/named/server.c index 2680ec47d0..932d40c59b 100644 --- a/bin/named/server.c +++ b/bin/named/server.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: server.c,v 1.510 2008/06/23 23:15:59 jinmei Exp $ */ +/* $Id: server.c,v 1.511 2008/07/11 23:05:45 jinmei Exp $ */ /*! \file */ @@ -2905,6 +2905,7 @@ load_configuration(const char *filename, ns_server_t *server, in_port_t listen_port, udpport_low, udpport_high; isc_portset_t *v4portset = NULL; isc_portset_t *v6portset = NULL; + isc_resourcevalue_t nfiles; int i; cfg_aclconfctx_init(&aclconfctx); @@ -2994,6 +2995,28 @@ load_configuration(const char *filename, ns_server_t *server, */ set_limits(maps); + /* + * Check if max number of open sockets that the system allows is + * sufficiently large. Failing this condition is not necessarily fatal, + * but may cause subsequent runtime failures for a busy recursive + * server. + */ + result = isc_resource_getcurlimit(isc_resource_openfiles, &nfiles); + if (result == ISC_R_SUCCESS) { + unsigned int maxsocks; + + result = isc_socketmgr_getmaxsockets(ns_g_socketmgr, &maxsocks); + if (result == ISC_R_SUCCESS && + ((isc_resourcevalue_t)maxsocks > nfiles) { + isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, + NS_LOGMODULE_SERVER, ISC_LOG_WARNING, + "max open files " + "(%" ISC_PRINT_QUADFORMAT "u)" + " is smaller than max sockets (%u)", + nfiles, maxsocks); + } + } + /* * Configure various server options. */ diff --git a/lib/isc/include/isc/resource.h b/lib/isc/include/isc/resource.h index 7a615655f8..f32b632eca 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.12 2008/07/11 23:05:46 jinmei Exp $ */ #ifndef ISC_RESOURCE_H #define ISC_RESOURCE_H 1 @@ -81,6 +81,16 @@ 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_getcurlimit(isc_resource_t resource, isc_resourcevalue_t *value); +/*%< + * Same as isc_resource_getlimit(), but returns the current (soft) limit. + * + * Returns: + *\li #ISC_R_SUCCESS Success. + *\li #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 8236adcf16..530e684b65 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.77 2008/07/03 00:13:25 each Exp $ */ +/* $Id: socket.h,v 1.78 2008/07/11 23:05:46 jinmei Exp $ */ #ifndef ISC_SOCKET_H #define ISC_SOCKET_H 1 @@ -755,6 +755,22 @@ isc_socketmgr_create(isc_mem_t *mctx, isc_socketmgr_t **managerp); *\li #ISC_R_UNEXPECTED */ +isc_result_t +isc_socketmgr_getmaxsockets(isc_socketmgr_t *manager, unsigned int *nsockp); +/*%< + * Returns in "*nsockp" the maximum number of sockets this manager may open. + * + * Requires: + * + *\li '*manager' is a valid isc_socketmgr_t. + *\li 'nsockp' is not NULL. + * + * Returns: + * + *\li #ISC_R_SUCCESS + *\li #ISC_R_NOTIMPLEMENTED + */ + void isc_socketmgr_destroy(isc_socketmgr_t **managerp); /*%< diff --git a/lib/isc/unix/resource.c b/lib/isc/unix/resource.c index 97ffd75747..aaaec1b6ff 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.17 2008/01/25 23:50:38 jinmei Exp $ */ +/* $Id: resource.c,v 1.18 2008/07/11 23:05:46 jinmei Exp $ */ #include @@ -171,3 +171,20 @@ isc_resource_getlimit(isc_resource_t resource, isc_resourcevalue_t *value) { return (result); } + +isc_result_t +isc_resource_getcurlimit(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 e3157de3c7..b5367f7e64 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.286 2008/07/03 00:13:25 each Exp $ */ +/* $Id: socket.c,v 1.287 2008/07/11 23:05:46 jinmei Exp $ */ /*! \file */ @@ -3489,6 +3489,16 @@ free_manager: return (result); } +isc_result_t +isc_socketmgr_getmaxsockets(isc_socketmgr_t *manager, unsigned int *nsockp) { + REQUIRE(VALID_MANAGER(manager)); + REQUIRE(nsockp != NULL); + + *nsockp = manager->maxsocks; + + return (ISC_R_SUCCESS); +} + void isc_socketmgr_destroy(isc_socketmgr_t **managerp) { isc_socketmgr_t *manager; diff --git a/lib/isc/win32/libisc.def b/lib/isc/win32/libisc.def index 1480d85e92..5dcc73dd0d 100644 --- a/lib/isc/win32/libisc.def +++ b/lib/isc/win32/libisc.def @@ -336,6 +336,7 @@ isc_ratelimiter_shutdown isc_refcount_init isc_region_compare isc_resource_getlimit +isc_resource_getcurlimit isc_resource_setlimit isc_result_register isc_result_totext @@ -417,6 +418,7 @@ isc_socket_sendv isc_socket_setname isc_socketmgr_create isc_socketmgr_destroy +isc_socketmgr_getmaxsockets isc_stdio_close isc_stdio_flush isc_stdio_open diff --git a/lib/isc/win32/resource.c b/lib/isc/win32/resource.c index 328b711ca6..228ca7dfd7 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.9 2008/07/11 23:05:46 jinmei Exp $ */ #include @@ -65,3 +65,8 @@ 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_getcurlimit(isc_resource_t resource, isc_resourcevalue_t *value) { + return (isc_resource_getlimit(resource, value)); +} diff --git a/lib/isc/win32/socket.c b/lib/isc/win32/socket.c index 374caf74e5..77f2900c6b 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.57 2008/07/03 00:13:25 each Exp $ */ +/* $Id: socket.c,v 1.58 2008/07/11 23:05:46 jinmei Exp $ */ /* This code has been rewritten to take advantage of Windows Sockets * I/O Completion Ports and Events. I/O Completion Ports is ONLY @@ -2873,6 +2873,14 @@ isc_socketmgr_create(isc_mem_t *mctx, isc_socketmgr_t **managerp) { return (ISC_R_SUCCESS); } +isc_result_t +isc_socketmgr_getmaxsockets(isc_socketmgr_t *manager, unsigned int *nsockp) { + REQUIRE(VALID_MANAGER(manager)); + REQUIRE(nsockp != NULL); + + return (ISC_R_NOTIMPLEMENTED); +} + void isc_socketmgr_destroy(isc_socketmgr_t **managerp) { isc_socketmgr_t *manager;