]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
2398. [bug] Improve file descriptor management. New,
authorMark Andrews <marka@isc.org>
Wed, 23 Jul 2008 12:04:33 +0000 (12:04 +0000)
committerMark Andrews <marka@isc.org>
Wed, 23 Jul 2008 12:04:33 +0000 (12:04 +0000)
                        temporary, named.conf option reserved-sockets,
                        default 512. [RT #18344]

13 files changed:
CHANGES
bin/named/config.c
bin/named/named.conf.docbook
bin/named/server.c
doc/arm/Bv9ARM-book.xml
lib/isc/include/isc/resource.h
lib/isc/include/isc/socket.h
lib/isc/unix/resource.c
lib/isc/unix/socket.c
lib/isc/win32/libisc.def
lib/isc/win32/resource.c
lib/isc/win32/socket.c
lib/isccfg/namedconf.c

diff --git a/CHANGES b/CHANGES
index 9ad0555ac5a3e8f58bed555d436cde209b3ea887..24bf23c968402bfa8d467a1549f9a497399f6ce9 100644 (file)
--- 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]
+
 2396.  [bug]           Don't set SO_REUSEADDR for randomized ports.
                        [RT #18336]
 
index 907d3b5d85f736d8e9b509a1080a9758399ef03b..1dcd2dd7e317d9a0c992fff82f09e4f2a6bc25a3 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: config.c,v 1.47.18.32.10.1 2008/07/23 11:13:47 marka Exp $ */
+/* $Id: config.c,v 1.47.18.32.10.2 2008/07/23 12:04:32 marka Exp $ */
 
 /*! \file */
 
@@ -99,6 +99,7 @@ options {\n\
        use-ixfr true;\n\
        edns-udp-size 4096;\n\
        max-udp-size 4096;\n\
+       reserved-sockets 512;\n\
 \n\
        /* view */\n\
        allow-notify {none;};\n\
index e4cfcc7fef015953536e1bc72aaf2322973f5188..254d4ab2354adc83459004b7efae75697c1ca3f4 100644 (file)
@@ -17,7 +17,7 @@
  - PERFORMANCE OF THIS SOFTWARE.
 -->
 
-<!-- $Id: named.conf.docbook,v 1.1.2.29 2007/08/28 07:20:01 tbox Exp $ -->
+<!-- $Id: named.conf.docbook,v 1.1.2.29.12.1 2008/07/23 12:04:32 marka Exp $ -->
 <refentry>
   <refentryinfo>
     <date>Aug 13, 2004</date>
@@ -201,6 +201,7 @@ options {
        port <replaceable>integer</replaceable>;
        querylog <replaceable>boolean</replaceable>;
        recursing-file <replaceable>quoted_string</replaceable>;
+       reserved-sockets <replaceable>integer</replaceable>;
        random-device <replaceable>quoted_string</replaceable>;
        recursive-clients <replaceable>integer</replaceable>;
        serial-query-rate <replaceable>integer</replaceable>;
index 394f9fbba680055d0e25d74078ddf89a57d13c58..79bd125c5498da62fde05ba4c6bd1c47109fd3f3 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: server.c,v 1.419.18.57.10.2 2008/07/23 07:28:55 tbox Exp $ */
+/* $Id: server.c,v 1.419.18.57.10.3 2008/07/23 12:04:32 marka Exp $ */
 
 /*! \file */
 
@@ -2696,27 +2696,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;
+       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 *maps[3];
-       const cfg_obj_t *builtin_views;
-       const cfg_listelt_t *element;
+       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);
@@ -2796,6 +2798,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.
         */
index a078cb2373fccdc179c9b8ac89395801d7890a74..24642c13c2b769575168b24b1f1d2389f588ba10 100644 (file)
@@ -18,7 +18,7 @@
  - PERFORMANCE OF THIS SOFTWARE.
 -->
 
-<!-- File: $Id: Bv9ARM-book.xml,v 1.241.18.82.8.2 2008/07/23 07:28:55 tbox Exp $ -->
+<!-- File: $Id: Bv9ARM-book.xml,v 1.241.18.82.8.3 2008/07/23 12:04:32 marka Exp $ -->
 <book xmlns:xi="http://www.w3.org/2001/XInclude">
   <title>BIND 9 Administrator Reference Manual</title>
 
@@ -4442,6 +4442,7 @@ category notify { null; };
     <optional> max-transfer-idle-in <replaceable>number</replaceable>; </optional>
     <optional> max-transfer-idle-out <replaceable>number</replaceable>; </optional>
     <optional> tcp-clients <replaceable>number</replaceable>; </optional>
+    <optional> reserved-sockets <replaceable>number</replaceable>; </optional>
     <optional> recursive-clients <replaceable>number</replaceable>; </optional>
     <optional> serial-query-rate <replaceable>number</replaceable>; </optional>
     <optional> serial-queries <replaceable>number</replaceable>; </optional>
@@ -6606,6 +6607,23 @@ query-source-v6 address * port *;
               </listitem>
             </varlistentry>
 
+            <varlistentry>
+              <term><command>reserved-sockets</command></term>
+              <listitem>
+                <para>
+                 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 <literal>512</literal>.
+                 The minimum value is <literal>128</literal> and the
+                 maximum value is <literal>128</literal> less than
+                 'files' or FD_SETSIZE (whichever is smaller).  This
+                 option may be removed in the future.
+                </para>
+              </listitem>
+            </varlistentry>
+
             <varlistentry>
               <term><command>max-cache-size</command></term>
               <listitem>
index 53b2a4e5a28598d7cce782d994602df5c771668d..80e48832523995153751e6b79b69a32e2989f317 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: resource.h,v 1.5.18.2 2005/04/29 00:17:02 marka Exp $ */
+/* $Id: resource.h,v 1.5.18.2.52.1 2008/07/23 12:04:32 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 */
index a7f129790ce254c6f451e6c9f97b8f872e1b4434..8f09b1361d2d07dd319989eca4196a7625342b3f 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: socket.h,v 1.57.18.6.46.2 2008/07/23 07:28:57 tbox Exp $ */
+/* $Id: socket.h,v 1.57.18.6.46.3 2008/07/23 12:04:32 marka Exp $ */
 
 #ifndef ISC_SOCKET_H
 #define ISC_SOCKET_H 1
@@ -749,6 +749,12 @@ isc_socket_permunix(isc_sockaddr_t *sockaddr, isc_uint32_t perm,
  * \li #ISC_R_FAILURE
  */
 
+void
+isc__socketmgr_setreserved(isc_socketmgr_t *mgr, isc_uint32_t);
+/*%<
+ * Temporary.  For use by named only.
+ */
+
 ISC_LANG_ENDDECLS
 
 #endif /* ISC_SOCKET_H */
index d23bf4edc545c1a5b9e24474c68c968dfec9d9f3..b957c16750ae1b4fa5395ab18ade1832e57a0b26 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: resource.c,v 1.12.944.1 2008/07/23 11:30:56 marka Exp $ */
+/* $Id: resource.c,v 1.12.944.2 2008/07/23 12:04:32 marka Exp $ */
 
 #include <config.h>
 
@@ -232,3 +232,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);
+}
index 841795ac24c4f55ef73dc4ed80d9caf0b79ffe32..007067042061cd0c45d2e467b014ddc5350b1cb5 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: socket.c,v 1.237.18.29.10.2 2008/07/23 07:28:57 tbox Exp $ */
+/* $Id: socket.c,v 1.237.18.29.10.3 2008/07/23 12:04:32 marka Exp $ */
 
 /*! \file */
 
@@ -209,6 +209,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;
@@ -1478,9 +1479,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;
@@ -2405,6 +2415,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.
  */
@@ -2486,6 +2504,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
index 9e5739a63facdecd35889a7c45b6401683fa55f0..00f0e29830a9b65ecc115d734761777dfa49f50e 100644 (file)
@@ -33,6 +33,7 @@ isc__mem_putanddetach
 isc__mem_strdup
 isc__mempool_get
 isc__mempool_put
+isc__socketmgr_setminudp
 isc__strerror
 isc_app_block
 isc_app_finish
index c3d74ea96140e3a75d20d8144b57cd40459b3453..2e50ae77810578e12b3b2ddfa762d6addb5c045c 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: resource.c,v 1.6 2004/03/05 05:11:58 marka Exp $ */
+/* $Id: resource.c,v 1.6.946.1 2008/07/23 12:04:32 marka Exp $ */
 
 #include <config.h>
 
@@ -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);
+}
index c9d6c1efcc449b810c0d1cbee6115a3b8df877aa..b74f21014d592a1e49bc3c0bdf89b736a5d0e002 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: socket.c,v 1.30.18.20.12.2 2008/07/23 07:28:57 tbox Exp $ */
+/* $Id: socket.c,v 1.30.18.20.12.3 2008/07/23 12:04:32 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
@@ -3849,3 +3849,9 @@ isc_socket_permunix(isc_sockaddr_t *addr, isc_uint32_t perm,
        UNUSED(group);
        return (ISC_R_NOTIMPLEMENTED);
 }
+
+void
+isc__socketmgr_setreserved(isc_socketmgr_t *manager, isc_uint32_t reserved) {
+       UNUSED(manager);
+       UNUSED(reserved);
+}
index 65e30a2f3732ca929a15892028ee0bd62a86a36c..dc7c291df53713cb5c752f6bcf2311610eed795e 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: namedconf.c,v 1.30.18.38 2006/05/03 01:46:40 marka Exp $ */
+/* $Id: namedconf.c,v 1.30.18.38.50.1 2008/07/23 12:04:33 marka Exp $ */
 
 /*! \file */
 
@@ -634,6 +634,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 },