]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Remove isc_resource API and set limits directly in named_os unit
authorOndřej Surý <ondrej@isc.org>
Sun, 13 Nov 2022 10:04:30 +0000 (11:04 +0100)
committerOndřej Surý <ondrej@isc.org>
Wed, 7 Dec 2022 18:40:00 +0000 (19:40 +0100)
The only function left in the isc_resource API was setting the file
limit.  Replace the whole unit with a simple getrlimit to check the
maximum value of RLIMIT_NOFILE and set the maximum back to rlimit_cur.

This is more compatible than trying to set RLIMIT_UNLIMITED on the
RLIMIT_NOFILE as it doesn't work on Linux (see man 5 proc on
/proc/sys/fs/nr_open), neither it does on Darwin kernel (see man 2
getrlimit).

The only place where the maximum value could be raised under privileged
user would be BSDs, but the `named_os_adjustnofile()` were not called
there before.  We would apply the increased limits only on Linux and Sun
platforms.

bin/named/include/named/globals.h
bin/named/main.c
bin/named/os.c
bin/named/server.c
bin/named/zoneconf.c
lib/isc/Makefile.am
lib/isc/include/isc/resource.h [deleted file]
lib/isc/include/isc/types.h
lib/isc/resource.c [deleted file]
lib/isccfg/namedconf.c
tests/libtest/ns.c

index de2234967890f9e4074a8398d5365d7265911353..6d46f12589a5c17e338b22e755a07dfaa9fe84ca 100644 (file)
@@ -106,11 +106,6 @@ EXTERN dns_name_t                      named_g_sessionkeyname;
 EXTERN bool named_g_conffileset                    INIT(false);
 EXTERN cfg_aclconfctx_t *named_g_aclconfctx INIT(NULL);
 
-/*
- * Initial resource limits.
- */
-EXTERN isc_resourcevalue_t named_g_initopenfiles INIT(0);
-
 /*
  * Misc.
  */
index 59706f1f2413d95d52513fe20cb34f93f6afa9eb..a75bbdb6e564b98a3cd406c044ba75a6fb91891b 100644 (file)
@@ -35,7 +35,6 @@
 #include <isc/netmgr.h>
 #include <isc/os.h>
 #include <isc/print.h>
-#include <isc/resource.h>
 #include <isc/result.h>
 #include <isc/signal.h>
 #include <isc/stdio.h>
@@ -1043,7 +1042,6 @@ create_managers(void) {
 static void
 setup(void) {
        isc_result_t result;
-       isc_resourcevalue_t old_openfiles;
        ns_server_t *sctx;
 #ifdef HAVE_LIBSCF
        char *instance = NULL;
@@ -1216,30 +1214,11 @@ setup(void) {
                      NAMED_LOGMODULE_MAIN, ISC_LOG_NOTICE,
                      "----------------------------------------------------");
 
-       /*
-        * Get the initial resource limits.
-        */
-       RUNTIME_CHECK(isc_resource_getlimit(isc_resource_openfiles,
-                                           &named_g_initopenfiles) ==
-                     ISC_R_SUCCESS);
-
        /*
         * System resources cannot effectively be tuned on some systems.
         * Raise the limit in such cases for safety.
         */
-       old_openfiles = named_g_initopenfiles;
        named_os_adjustnofile();
-       RUNTIME_CHECK(isc_resource_getlimit(isc_resource_openfiles,
-                                           &named_g_initopenfiles) ==
-                     ISC_R_SUCCESS);
-       if (old_openfiles != named_g_initopenfiles) {
-               isc_log_write(named_g_lctx, NAMED_LOGCATEGORY_GENERAL,
-                             NAMED_LOGMODULE_MAIN, ISC_LOG_NOTICE,
-                             "adjusted limit on open files from "
-                             "%" PRIu64 " to "
-                             "%" PRIu64,
-                             old_openfiles, named_g_initopenfiles);
-       }
 
        /*
         * If the named configuration filename is relative, prepend the current
index 3506a5e605cf8154b419f75734fecc5cb22fd050..699ca2f2569827027c89f1e9b8176645031f2243 100644 (file)
@@ -14,6 +14,7 @@
 /*! \file */
 #include <stdarg.h>
 #include <stdbool.h>
+#include <sys/resource.h>
 #include <sys/stat.h>
 #include <sys/types.h> /* dev_t FreeBSD 2.1 */
 #ifdef HAVE_UNAME
 #include <isc/buffer.h>
 #include <isc/file.h>
 #include <isc/print.h>
-#include <isc/resource.h>
 #include <isc/result.h>
 #include <isc/strerr.h>
 #include <isc/string.h>
 #include <isc/util.h>
 
 #include <named/globals.h>
+#include <named/log.h>
 #include <named/main.h>
 #include <named/os.h>
 #ifdef HAVE_LIBSCF
@@ -615,23 +616,47 @@ ns_os_uid(void) {
 
 void
 named_os_adjustnofile(void) {
-#if defined(__linux__) || defined(__sun)
-       isc_result_t result;
-       isc_resourcevalue_t newvalue;
+       int r;
+       struct rlimit rl;
+       rlim_t rlim_old;
+       char strbuf[ISC_STRERRORSIZE];
 
-       /*
-        * Linux: max number of open files specified by one thread doesn't seem
-        * to apply to other threads on Linux.
-        * Sun: restriction needs to be removed sooner when hundreds of CPUs
-        * are available.
-        */
-       newvalue = ISC_RESOURCE_UNLIMITED;
+       r = getrlimit(RLIMIT_NOFILE, &rl);
+       if (r != 0) {
+               goto fail;
+       }
+
+       rlim_old = rl.rlim_cur;
 
-       result = isc_resource_setlimit(isc_resource_openfiles, newvalue);
-       if (result != ISC_R_SUCCESS) {
-               named_main_earlywarning("couldn't adjust limit on open files");
+       if (rl.rlim_cur == rl.rlim_max) {
+               isc_log_write(named_g_lctx, NAMED_LOGCATEGORY_GENERAL,
+                             NAMED_LOGMODULE_MAIN, ISC_LOG_NOTICE,
+                             "the limit on open files is already at the "
+                             "maximum allowed value: "
+                             "%" PRIu64,
+                             (uint64_t)rl.rlim_max);
+               return;
+       }
+
+       rl.rlim_cur = rl.rlim_max;
+       r = setrlimit(RLIMIT_NOFILE, &rl);
+       if (r != 0) {
+               goto fail;
        }
-#endif /* if defined(__linux__) || defined(__sun) */
+
+       isc_log_write(named_g_lctx, NAMED_LOGCATEGORY_GENERAL,
+                     NAMED_LOGMODULE_MAIN, ISC_LOG_NOTICE,
+                     "adjusted limit on open files from "
+                     "%" PRIu64 " to "
+                     "%" PRIu64,
+                     (uint64_t)rlim_old, (uint64_t)rl.rlim_cur);
+       return;
+
+fail:
+       strerror_r(errno, strbuf, sizeof(strbuf));
+       named_main_earlywarning("adjusting limit on open files failed: %s",
+                               strbuf);
+       return;
 }
 
 void
index 63535328a0d9c6db644775f3c1b66303255aca8b..09eb53e2ed201b86f771807adfb6da5944e3709c 100644 (file)
@@ -4354,8 +4354,7 @@ configure_view(dns_view_t *view, dns_viewlist_t *viewlist, cfg_obj_t *config,
                max_cache_size = SIZE_AS_PERCENT;
                max_cache_size_percent = cfg_obj_aspercentage(obj);
        } else {
-               isc_resourcevalue_t value;
-               value = cfg_obj_asuint64(obj);
+               uint64_t value = cfg_obj_asuint64(obj);
                if (value > SIZE_MAX) {
                        cfg_obj_log(obj, named_g_lctx, ISC_LOG_WARNING,
                                    "'max-cache-size "
index f7e5914fbd2658febbbb99b8db249f2212daa41f..795db7bf6eb6c8e4ad586c989da44af63c313071 100644 (file)
@@ -1362,8 +1362,7 @@ named_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig,
                                journal_size = -1;
                        }
                } else {
-                       isc_resourcevalue_t value;
-                       value = cfg_obj_asuint64(obj);
+                       uint64_t value = cfg_obj_asuint64(obj);
                        if (value > DNS_JOURNAL_SIZE_MAX) {
                                cfg_obj_log(obj, named_g_lctx, ISC_LOG_ERROR,
                                            "'max-journal-size "
@@ -1508,8 +1507,7 @@ named_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig,
                                journal_size = -1;
                        }
                } else {
-                       isc_resourcevalue_t value;
-                       value = cfg_obj_asuint64(obj);
+                       uint64_t value = cfg_obj_asuint64(obj);
                        if (value > DNS_JOURNAL_SIZE_MAX) {
                                cfg_obj_log(obj, named_g_lctx, ISC_LOG_ERROR,
                                            "'max-journal-size "
index 2d8976a36339d9b3ea05e0096cb70d6126f53b4f..f44a5a00dd5941f245d9bf2b6339ac000b283ba6 100644 (file)
@@ -77,7 +77,6 @@ libisc_la_HEADERS =                   \
        include/isc/refcount.h          \
        include/isc/regex.h             \
        include/isc/region.h            \
-       include/isc/resource.h          \
        include/isc/result.h            \
        include/isc/rwlock.h            \
        include/isc/safe.h              \
@@ -189,7 +188,6 @@ libisc_la_SOURCES =         \
        ratelimiter.c           \
        regex.c                 \
        region.c                \
-       resource.c              \
        result.c                \
        safe.c                  \
        serial.c                \
diff --git a/lib/isc/include/isc/resource.h b/lib/isc/include/isc/resource.h
deleted file mode 100644 (file)
index dc4b2b1..0000000
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
- *
- * SPDX-License-Identifier: MPL-2.0
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, you can obtain one at https://mozilla.org/MPL/2.0/.
- *
- * See the COPYRIGHT file distributed with this work for additional
- * information regarding copyright ownership.
- */
-
-#pragma once
-
-/*! \file isc/resource.h */
-
-#include <isc/lang.h>
-#include <isc/types.h>
-
-#define ISC_RESOURCE_UNLIMITED ((isc_resourcevalue_t)UINT64_MAX)
-
-ISC_LANG_BEGINDECLS
-
-isc_result_t
-isc_resource_setlimit(isc_resource_t resource, isc_resourcevalue_t value);
-/*%<
- * Set the maximum limit for a system resource.
- *
- * Notes:
- *\li  If 'value' exceeds the maximum possible on the operating system,
- *     it is silently limited to that maximum -- or to "infinity", if
- *     the operating system has that concept.  #ISC_RESOURCE_UNLIMITED
- *     can be used to explicitly ask for the maximum.
- *
- * Requires:
- *\li  'resource' is a valid member of the isc_resource_t enumeration.
- *
- * Returns:
- *\li  #ISC_R_SUCCESS  Success.
- *\li  #ISC_R_NOTIMPLEMENTED   'resource' is not a type known by the OS.
- *\li  #ISC_R_NOPERM   The calling process did not have adequate permission
- *                     to change the resource limit.
- */
-
-isc_result_t
-isc_resource_getlimit(isc_resource_t resource, isc_resourcevalue_t *value);
-/*%<
- * Get the maximum limit for a system resource.
- *
- * Notes:
- *\li  'value' is set to the maximum limit.
- *
- *\li  #ISC_RESOURCE_UNLIMITED is the maximum value of isc_resourcevalue_t.
- *
- *\li  On many (all?) Unix systems, RLIM_INFINITY is a valid value that is
- *     significantly less than #ISC_RESOURCE_UNLIMITED, but which in practice
- *     behaves the same.
- *
- *\li  The current ISC libdns configuration file parser assigns a value
- *     of UINT32_MAX for a size_spec of "unlimited" and ISC_UNIT32_MAX - 1
- *     for "default", the latter of which is supposed to represent "the
- *     limit that was in force when the server started".  Since these are
- *     valid values in the middle of the range of isc_resourcevalue_t,
- *     there is the possibility for confusion over what exactly those
- *     particular values are supposed to represent in a particular context --
- *     discrete integral values or generalized concepts.
- *
- * Requires:
- *\li  'resource' is a valid member of the isc_resource_t enumeration.
- *
- * Returns:
- *\li  #ISC_R_SUCCESS          Success.
- *\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
index ecbbf48976346b58a78b1b93c1dec7bffe22353d..51a246dfabc4b955df408b96d91983692bb21277 100644 (file)
@@ -71,14 +71,13 @@ typedef struct isc_nmsocket  isc_nmsocket_t; /*%< Network manager socket */
 typedef struct isc_nmhandle     isc_nmhandle_t; /*%< Network manager handle */
 typedef struct isc_portset      isc_portset_t;  /*%< Port Set */
 typedef struct isc_quota        isc_quota_t;    /*%< Quota */
-typedef struct isc_ratelimiter  isc_ratelimiter_t;   /*%< Rate Limiter */
-typedef struct isc_region       isc_region_t;        /*%< Region */
-typedef uint64_t                isc_resourcevalue_t; /*%< Resource Value */
-typedef struct isc_signal       isc_signal_t;        /*%< Signal handler */
-typedef struct isc_sockaddr     isc_sockaddr_t;      /*%< Socket Address */
-typedef ISC_LIST(isc_sockaddr_t) isc_sockaddrlist_t;  /*%< Socket Address List
-                                                      * */
-typedef struct isc_stats      isc_stats_t;           /*%< Statistics */
+typedef struct isc_ratelimiter  isc_ratelimiter_t;  /*%< Rate Limiter */
+typedef struct isc_region       isc_region_t;       /*%< Region */
+typedef struct isc_signal       isc_signal_t;       /*%< Signal handler */
+typedef struct isc_sockaddr     isc_sockaddr_t;     /*%< Socket Address */
+typedef ISC_LIST(isc_sockaddr_t) isc_sockaddrlist_t; /*%< Socket Address List
+                                                     * */
+typedef struct isc_stats      isc_stats_t;          /*%< Statistics */
 typedef int_fast64_t         isc_statscounter_t;
 typedef struct isc_symtab     isc_symtab_t;    /*%< Symbol Table */
 typedef struct isc_task              isc_task_t;       /*%< Task */
@@ -96,19 +95,6 @@ typedef struct isc_nm_http_endpoints isc_nm_http_endpoints_t;
 
 typedef void (*isc_taskaction_t)(isc_task_t *, isc_event_t *);
 
-/*% Resource */
-typedef enum {
-       isc_resource_coresize = 1,
-       isc_resource_cputime,
-       isc_resource_datasize,
-       isc_resource_filesize,
-       isc_resource_lockedmemory,
-       isc_resource_openfiles,
-       isc_resource_processes,
-       isc_resource_residentsize,
-       isc_resource_stacksize
-} isc_resource_t;
-
 /*% Statistics formats (text file or XML) */
 typedef enum {
        isc_statsformat_file,
diff --git a/lib/isc/resource.c b/lib/isc/resource.c
deleted file mode 100644 (file)
index f696575..0000000
+++ /dev/null
@@ -1,208 +0,0 @@
-/*
- * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
- *
- * SPDX-License-Identifier: MPL-2.0
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, you can obtain one at https://mozilla.org/MPL/2.0/.
- *
- * See the COPYRIGHT file distributed with this work for additional
- * information regarding copyright ownership.
- */
-
-#include <inttypes.h>
-#include <stdbool.h>
-#include <sys/resource.h>
-#include <sys/time.h> /* Required on some systems for <sys/resource.h>. */
-#include <sys/types.h>
-
-#include <isc/resource.h>
-#include <isc/result.h>
-#include <isc/util.h>
-
-#ifdef __linux__
-#include <linux/fs.h> /* To get the large NR_OPEN. */
-#endif               /* ifdef __linux__ */
-
-#include "errno2result.h"
-
-static isc_result_t
-resource2rlim(isc_resource_t resource, int *rlim_resource) {
-       isc_result_t result = ISC_R_SUCCESS;
-
-       switch (resource) {
-       case isc_resource_coresize:
-               *rlim_resource = RLIMIT_CORE;
-               break;
-       case isc_resource_cputime:
-               *rlim_resource = RLIMIT_CPU;
-               break;
-       case isc_resource_datasize:
-               *rlim_resource = RLIMIT_DATA;
-               break;
-       case isc_resource_filesize:
-               *rlim_resource = RLIMIT_FSIZE;
-               break;
-       case isc_resource_lockedmemory:
-#ifdef RLIMIT_MEMLOCK
-               *rlim_resource = RLIMIT_MEMLOCK;
-#else  /* ifdef RLIMIT_MEMLOCK */
-               result = ISC_R_NOTIMPLEMENTED;
-#endif /* ifdef RLIMIT_MEMLOCK */
-               break;
-       case isc_resource_openfiles:
-#ifdef RLIMIT_NOFILE
-               *rlim_resource = RLIMIT_NOFILE;
-#else  /* ifdef RLIMIT_NOFILE */
-               result = ISC_R_NOTIMPLEMENTED;
-#endif /* ifdef RLIMIT_NOFILE */
-               break;
-       case isc_resource_processes:
-#ifdef RLIMIT_NPROC
-               *rlim_resource = RLIMIT_NPROC;
-#else  /* ifdef RLIMIT_NPROC */
-               result = ISC_R_NOTIMPLEMENTED;
-#endif /* ifdef RLIMIT_NPROC */
-               break;
-       case isc_resource_residentsize:
-#ifdef RLIMIT_RSS
-               *rlim_resource = RLIMIT_RSS;
-#else  /* ifdef RLIMIT_RSS */
-               result = ISC_R_NOTIMPLEMENTED;
-#endif /* ifdef RLIMIT_RSS */
-               break;
-       case isc_resource_stacksize:
-               *rlim_resource = RLIMIT_STACK;
-               break;
-       default:
-               /*
-                * This test is not very robust if isc_resource_t
-                * changes, but generates a clear assertion message.
-                */
-               REQUIRE(resource >= isc_resource_coresize &&
-                       resource <= isc_resource_stacksize);
-
-               result = ISC_R_RANGE;
-               break;
-       }
-
-       return (result);
-}
-
-isc_result_t
-isc_resource_setlimit(isc_resource_t resource, isc_resourcevalue_t value) {
-       struct rlimit rl;
-       rlim_t rlim_value;
-       int unixresult;
-       int unixresource;
-       isc_result_t result;
-
-       result = resource2rlim(resource, &unixresource);
-       if (result != ISC_R_SUCCESS) {
-               return (result);
-       }
-
-       if (value == ISC_RESOURCE_UNLIMITED) {
-               rlim_value = RLIM_INFINITY;
-       } else {
-               /*
-                * Carefully ensure the range of rlim_t is not overflowed, by
-                * calculating how many bytes wider is isc_resourcevalue_t than
-                * rlim_t, and whether rlim_t has a sign bit.
-                */
-               isc_resourcevalue_t rlim_max = UINT64_MAX;
-               size_t wider = sizeof(rlim_max) - sizeof(rlim_t);
-               size_t sign_bit = (size_t)(0.0 > (double)(rlim_t)-1);
-
-               rlim_max >>= CHAR_BIT * wider + sign_bit;
-               rlim_value = ISC_MIN(value, rlim_max);
-       }
-
-       rl.rlim_cur = rl.rlim_max = rlim_value;
-       unixresult = setrlimit(unixresource, &rl);
-
-       if (unixresult == 0) {
-               return (ISC_R_SUCCESS);
-       }
-
-#if defined(OPEN_MAX) && defined(__APPLE__)
-       /*
-        * The Darwin kernel doesn't accept RLIM_INFINITY for rlim_cur; the
-        * maximum possible value is OPEN_MAX.  BIND8 used to use
-        * sysconf(_SC_OPEN_MAX) for such a case, but this value is much
-        * smaller than OPEN_MAX and is not really effective.
-        */
-       if (resource == isc_resource_openfiles && rlim_value == RLIM_INFINITY) {
-               rl.rlim_cur = OPEN_MAX;
-               unixresult = setrlimit(unixresource, &rl);
-               if (unixresult == 0) {
-                       return (ISC_R_SUCCESS);
-               }
-       }
-#elif defined(__linux__)
-#ifndef NR_OPEN
-#define NR_OPEN (1024 * 1024)
-#endif /* ifndef NR_OPEN */
-
-       /*
-        * Some Linux kernels don't accept RLIM_INFINIT; the maximum
-        * possible value is the NR_OPEN defined in linux/fs.h.
-        */
-       if (resource == isc_resource_openfiles && rlim_value == RLIM_INFINITY) {
-               rl.rlim_cur = rl.rlim_max = NR_OPEN;
-               unixresult = setrlimit(unixresource, &rl);
-               if (unixresult == 0) {
-                       return (ISC_R_SUCCESS);
-               }
-       }
-#endif /* if defined(OPEN_MAX) && defined(__APPLE__) */
-       if (resource == isc_resource_openfiles && rlim_value == RLIM_INFINITY) {
-               if (getrlimit(unixresource, &rl) == 0) {
-                       rl.rlim_cur = rl.rlim_max;
-                       unixresult = setrlimit(unixresource, &rl);
-                       if (unixresult == 0) {
-                               return (ISC_R_SUCCESS);
-                       }
-               }
-       }
-       return (isc__errno2result(errno));
-}
-
-isc_result_t
-isc_resource_getlimit(isc_resource_t resource, isc_resourcevalue_t *value) {
-       int unixresource;
-       struct rlimit rl;
-       isc_result_t result;
-
-       result = resource2rlim(resource, &unixresource);
-       if (result != ISC_R_SUCCESS) {
-               return (result);
-       }
-
-       if (getrlimit(unixresource, &rl) != 0) {
-               return (isc__errno2result(errno));
-       }
-
-       *value = rl.rlim_max;
-       return (ISC_R_SUCCESS);
-}
-
-isc_result_t
-isc_resource_getcurlimit(isc_resource_t resource, isc_resourcevalue_t *value) {
-       int unixresource;
-       struct rlimit rl;
-       isc_result_t result;
-
-       result = resource2rlim(resource, &unixresource);
-       if (result != ISC_R_SUCCESS) {
-               return (result);
-       }
-
-       if (getrlimit(unixresource, &rl) != 0) {
-               return (isc__errno2result(errno));
-       }
-
-       *value = rl.rlim_cur;
-       return (ISC_R_SUCCESS);
-}
index 9543c1a02e452bb15c8ad89440a66e90480f707a..0ea0cf151feeba8390188941b4dac416f4029d2f 100644 (file)
@@ -2651,7 +2651,7 @@ cfg_type_t cfg_type_addzoneconf = { "addzoneconf",     cfg_parse_mapbody,
                                    &cfg_rep_map,      addzoneconf_clausesets };
 
 static isc_result_t
-parse_unitstring(char *str, isc_resourcevalue_t *valuep) {
+parse_unitstring(char *str, uint64_t *valuep) {
        char *endp;
        unsigned int len;
        uint64_t value;
index 3c813fc6baca2261fe99fff9aa9be853371c0b25..079d80b8d7c95932223f566b787efab75b4f9812 100644 (file)
@@ -30,7 +30,6 @@
 #include <isc/os.h>
 #include <isc/print.h>
 #include <isc/random.h>
-#include <isc/resource.h>
 #include <isc/result.h>
 #include <isc/stdio.h>
 #include <isc/string.h>