mirror of
https://gitlab.isc.org/isc-projects/bind9
synced 2025-08-22 18:19:42 +00:00
4223. [func] Add support for setting max-cache-size to percentage
of available physical memory, set default to 90%. [RT #38442]
This commit is contained in:
parent
98a7f8c7ae
commit
e6d0a391f5
1
.gitignore
vendored
1
.gitignore
vendored
@ -54,3 +54,4 @@ unit/atf-src/test-programs/cpp_helpers
|
||||
unit/atf-src/test-programs/sh_helpers
|
||||
# ccc-analyzer store its results in .plist directories
|
||||
*.plist/
|
||||
*~
|
||||
|
4
CHANGES
4
CHANGES
@ -1,3 +1,7 @@
|
||||
4223. [func] Add support for setting max-cache-size to percentage
|
||||
of available physical memory, set default to 90%.
|
||||
[RT #38442]
|
||||
|
||||
4222. [func] Bias IPv6 servers when selecting the next server to
|
||||
query. [RT #40836]
|
||||
|
||||
|
@ -368,6 +368,7 @@ do_authors_lookup(dns_sdblookup_t *lookup) {
|
||||
"Bob Halley",
|
||||
"Evan Hunt",
|
||||
"JINMEI Tatuya",
|
||||
"Witold Krecicki",
|
||||
"David Lawrence",
|
||||
"Scott Mann",
|
||||
"Danny Mayer",
|
||||
|
@ -160,7 +160,7 @@ options {\n\
|
||||
max-ncache-ttl 10800; /* 3 hours */\n\
|
||||
max-cache-ttl 604800; /* 1 week */\n\
|
||||
transfer-format many-answers;\n\
|
||||
max-cache-size 0;\n\
|
||||
max-cache-size 90%;\n\
|
||||
check-names master fail;\n\
|
||||
check-names slave warn;\n\
|
||||
check-names response ignore;\n\
|
||||
|
@ -37,6 +37,7 @@
|
||||
#include <isc/hmacsha.h>
|
||||
#include <isc/httpd.h>
|
||||
#include <isc/lex.h>
|
||||
#include <isc/meminfo.h>
|
||||
#include <isc/parseint.h>
|
||||
#include <isc/portset.h>
|
||||
#include <isc/print.h>
|
||||
@ -131,6 +132,10 @@
|
||||
#define SIZE_MAX ((size_t)-1)
|
||||
#endif
|
||||
|
||||
#ifndef SIZE_AS_PERCENT
|
||||
#define SIZE_AS_PERCENT ((size_t)-2)
|
||||
#endif
|
||||
|
||||
#ifdef TUNE_LARGE
|
||||
#define RESOLVER_NTASKS 523
|
||||
#define UDPBUFFERS 32768
|
||||
@ -2400,6 +2405,7 @@ configure_view(dns_view_t *view, dns_viewlist_t *viewlist,
|
||||
isc_result_t result;
|
||||
unsigned int cleaning_interval;
|
||||
size_t max_cache_size;
|
||||
isc_uint32_t max_cache_size_percent = 0;
|
||||
size_t max_acache_size;
|
||||
size_t max_adb_size;
|
||||
isc_uint32_t lame_ttl, fail_ttl;
|
||||
@ -2685,6 +2691,9 @@ configure_view(dns_view_t *view, dns_viewlist_t *viewlist,
|
||||
str = cfg_obj_asstring(obj);
|
||||
INSIST(strcasecmp(str, "unlimited") == 0);
|
||||
max_cache_size = 0;
|
||||
} else if (cfg_obj_ispercentage(obj)) {
|
||||
max_cache_size = SIZE_AS_PERCENT;
|
||||
max_cache_size_percent = cfg_obj_aspercentage(obj);
|
||||
} else {
|
||||
isc_resourcevalue_t value;
|
||||
value = cfg_obj_asuint64(obj);
|
||||
@ -2701,6 +2710,26 @@ configure_view(dns_view_t *view, dns_viewlist_t *viewlist,
|
||||
max_cache_size = (size_t) value;
|
||||
}
|
||||
|
||||
if (max_cache_size == SIZE_AS_PERCENT) {
|
||||
isc_uint64_t totalphys = isc_meminfo_totalphys();
|
||||
max_cache_size = totalphys * max_cache_size_percent/100;
|
||||
if (totalphys == 0) {
|
||||
cfg_obj_log(obj, ns_g_lctx,
|
||||
ISC_LOG_WARNING,
|
||||
"Unable to determine amount of physical "
|
||||
"memory, setting 'max-cache-size' to "
|
||||
"unlimited");
|
||||
} else {
|
||||
cfg_obj_log(obj, ns_g_lctx,
|
||||
ISC_LOG_INFO,
|
||||
"'max-cache-size %d%%' "
|
||||
"- setting to %luMB (out of %luMB)",
|
||||
max_cache_size_percent,
|
||||
max_cache_size / (1024*1024),
|
||||
(unsigned long) totalphys / (1024*1024));
|
||||
}
|
||||
}
|
||||
|
||||
/* Check-names. */
|
||||
obj = NULL;
|
||||
result = ns_checknames_get(maps, "response", &obj);
|
||||
|
@ -28,7 +28,7 @@ options {
|
||||
listen-on { 10.53.0.2; };
|
||||
listen-on-v6 { none; };
|
||||
notify yes;
|
||||
max-cache-size 10000;
|
||||
max-cache-size 80%;
|
||||
disable-empty-zone 127.IN-ADDR.ARPA;
|
||||
};
|
||||
|
||||
|
3
bin/tests/system/checkconf/max-cache-size-good.conf
Normal file
3
bin/tests/system/checkconf/max-cache-size-good.conf
Normal file
@ -0,0 +1,3 @@
|
||||
options {
|
||||
max-cache-size 60%;
|
||||
};
|
@ -261,5 +261,12 @@ grep "zone shared.example/IN: loaded serial" < checkconf.out7 > /dev/null || ret
|
||||
if [ $ret != 0 ]; then echo "I:failed"; ret=1; fi
|
||||
status=`expr $status + $ret`
|
||||
|
||||
echo "I: check that named-checkconf prints max-cache-size <percentage> correctly"
|
||||
ret=0
|
||||
$CHECKCONF -p max-cache-size-good.conf > checkconf.out8 2>&1 || ret=1
|
||||
grep "max-cache-size 60%;" checkconf.out8 > /dev/null || ret=1
|
||||
if [ $ret != 0 ]; then echo "I:failed"; ret=1; fi
|
||||
status=`expr $status + $ret`
|
||||
|
||||
echo "I:exit status: $status"
|
||||
exit $status
|
||||
|
@ -2930,6 +2930,25 @@ $ORIGIN 0.0.0.0.0.0.0.0.8.b.d.0.1.0.0.2.ip6.arpa.
|
||||
</para>
|
||||
</entry>
|
||||
</row>
|
||||
<row rowsep="0">
|
||||
<entry colname="1">
|
||||
<para>
|
||||
<varname>size_or_percent</varname>
|
||||
</para>
|
||||
</entry>
|
||||
<entry colname="2">
|
||||
<para>
|
||||
<varname>size_spec</varname> or integer value
|
||||
followed by '%' to represent percents.
|
||||
</para>
|
||||
<para>
|
||||
The behaviour is exactly the same as
|
||||
<varname>size_spec</varname>, but
|
||||
<varname>size_or_percent</varname> allows also
|
||||
to specify a positive integer value followed by
|
||||
'%' sign to represent percents.
|
||||
</entry>
|
||||
</row>
|
||||
<row rowsep="0">
|
||||
<entry colname="1">
|
||||
<para>
|
||||
@ -4959,7 +4978,7 @@ badresp:1,adberr:0,findfail:0,valfail:0]
|
||||
<optional> additional-from-auth <replaceable>yes_or_no</replaceable> ; </optional>
|
||||
<optional> additional-from-cache <replaceable>yes_or_no</replaceable> ; </optional>
|
||||
<optional> random-device <replaceable>path_name</replaceable> ; </optional>
|
||||
<optional> max-cache-size <replaceable>size_spec</replaceable> ; </optional>
|
||||
<optional> max-cache-size <replaceable>size_or_percent</replaceable> ; </optional>
|
||||
<optional> match-mapped-addresses <replaceable>yes_or_no</replaceable>; </optional>
|
||||
<optional> filter-aaaa-on-v4 ( <replaceable>yes_or_no</replaceable> | <replaceable>break-dnssec</replaceable> ); </optional>
|
||||
<optional> filter-aaaa-on-v6 ( <replaceable>yes_or_no</replaceable> | <replaceable>break-dnssec</replaceable> ); </optional>
|
||||
@ -8747,7 +8766,7 @@ avoid-v6-udp-ports { 40000; range 50000 60000; };
|
||||
<listitem>
|
||||
<para>
|
||||
The maximum amount of memory to use for the
|
||||
server's cache, in bytes.
|
||||
server's cache, in bytes or % of total physical memory.
|
||||
When the amount of data in the cache
|
||||
reaches this limit, the server will cause records to
|
||||
expire prematurely based on an LRU based strategy so
|
||||
@ -8760,7 +8779,14 @@ avoid-v6-udp-ports { 40000; range 50000 60000; };
|
||||
and reset to 2MB.
|
||||
In a server with multiple views, the limit applies
|
||||
separately to the cache of each view.
|
||||
The default is <userinput>unlimited</userinput>.
|
||||
The default is <userinput>90%</userinput>.
|
||||
On systems where detection of amount of physical
|
||||
memory is not supported values represented as %
|
||||
fall back to unlimited.
|
||||
Note that the detection of physical memory is done only
|
||||
once at startup, so <command>named</command> will not
|
||||
adjust the cache size if the amount of physical memory
|
||||
is changed during runtime.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
@ -178,12 +178,12 @@ options {
|
||||
masterfile-format ( text | raw | map );
|
||||
masterfile-style ( full | relative );
|
||||
match-mapped-addresses <boolean>;
|
||||
max-acache-size <size_no_default>;
|
||||
max-cache-size <size_no_default>;
|
||||
max-acache-size ( unlimited | <sizeval> );
|
||||
max-cache-size ( unlimited | default | <sizeval> | <percentage> );
|
||||
max-cache-ttl <integer>;
|
||||
max-clients-per-query <integer>;
|
||||
max-ixfr-log-size ( unlimited | default | <sizeval> ); // obsolete
|
||||
max-journal-size <size_no_default>;
|
||||
max-journal-size ( unlimited | <sizeval> );
|
||||
max-ncache-ttl <integer>;
|
||||
max-recursion-depth <integer>;
|
||||
max-recursion-queries <integer>;
|
||||
@ -461,12 +461,12 @@ view <string> [ <class> ] {
|
||||
match-clients { <address_match_element>; ... };
|
||||
match-destinations { <address_match_element>; ... };
|
||||
match-recursive-only <boolean>;
|
||||
max-acache-size <size_no_default>;
|
||||
max-cache-size <size_no_default>;
|
||||
max-acache-size ( unlimited | <sizeval> );
|
||||
max-cache-size ( unlimited | default | <sizeval> | <percentage> );
|
||||
max-cache-ttl <integer>;
|
||||
max-clients-per-query <integer>;
|
||||
max-ixfr-log-size ( unlimited | default | <sizeval> ); // obsolete
|
||||
max-journal-size <size_no_default>;
|
||||
max-journal-size ( unlimited | <sizeval> );
|
||||
max-ncache-ttl <integer>;
|
||||
max-recursion-depth <integer>;
|
||||
max-recursion-queries <integer>;
|
||||
@ -645,7 +645,7 @@ view <string> [ <class> ] {
|
||||
port <integer> ] ) [ key <string> ]; ... };
|
||||
max-ixfr-log-size ( unlimited | default |
|
||||
<sizeval> ); // obsolete
|
||||
max-journal-size <size_no_default>;
|
||||
max-journal-size ( unlimited | <sizeval> );
|
||||
max-refresh-time <integer>;
|
||||
max-retry-time <integer>;
|
||||
max-transfer-idle-in <integer>;
|
||||
@ -746,7 +746,7 @@ zone <string> [ <class> ] {
|
||||
<ipv4_address> [ port <integer> ] | <ipv6_address> [ port
|
||||
<integer> ] ) [ key <string> ]; ... };
|
||||
max-ixfr-log-size ( unlimited | default | <sizeval> ); // obsolete
|
||||
max-journal-size <size_no_default>;
|
||||
max-journal-size ( unlimited | <sizeval> );
|
||||
max-refresh-time <integer>;
|
||||
max-retry-time <integer>;
|
||||
max-transfer-idle-in <integer>;
|
||||
|
@ -37,9 +37,10 @@ CWARNINGS =
|
||||
UNIXOBJS = @ISC_ISCIPV6_O@ @ISC_ISCPK11_API_O@ \
|
||||
unix/app.@O@ unix/dir.@O@ unix/entropy.@O@ \
|
||||
unix/errno2result.@O@ unix/file.@O@ unix/fsaccess.@O@ \
|
||||
unix/interfaceiter.@O@ unix/keyboard.@O@ unix/net.@O@ \
|
||||
unix/os.@O@ unix/resource.@O@ unix/socket.@O@ unix/stdio.@O@ \
|
||||
unix/stdtime.@O@ unix/strerror.@O@ unix/syslog.@O@ unix/time.@O@
|
||||
unix/interfaceiter.@O@ unix/keyboard.@O@ unix/meminfo.@O@ \
|
||||
unix/net.@O@ unix/os.@O@ unix/resource.@O@ unix/socket.@O@ \
|
||||
unix/stdio.@O@ unix/stdtime.@O@ unix/strerror.@O@ \
|
||||
unix/syslog.@O@ unix/time.@O@
|
||||
|
||||
NLSOBJS = nls/msgcat.@O@
|
||||
|
||||
@ -48,8 +49,8 @@ THREADOPTOBJS = @ISC_THREAD_DIR@/condition.@O@ @ISC_THREAD_DIR@/mutex.@O@
|
||||
THREADOBJS = @THREADOPTOBJS@ @ISC_THREAD_DIR@/thread.@O@
|
||||
|
||||
WIN32OBJS = win32/condition.@O@ win32/dir.@O@ win32/file.@O@ \
|
||||
win32/fsaccess.@O@ win32/once.@O@ win32/stdtime.@O@ \
|
||||
win32/thread.@O@ win32/time.@O@
|
||||
win32/fsaccess.@O@ win32/meminfo.@O@ win32/once.@O@ \
|
||||
win32/stdtime.@O@ win32/thread.@O@ win32/time.@O@
|
||||
|
||||
# Alphabetically
|
||||
OBJS = @ISC_EXTRA_OBJS@ @ISC_PK11_O@ @ISC_PK11_RESULT_O@ \
|
||||
|
35
lib/isc/include/isc/meminfo.h
Normal file
35
lib/isc/include/isc/meminfo.h
Normal file
@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Internet Systems Consortium, Inc. ("ISC")
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
|
||||
* REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
* AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
|
||||
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
||||
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
|
||||
* OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef ISC_MEMINFO_H
|
||||
#define ISC_MEMINFO_H 1
|
||||
|
||||
#include <isc/types.h>
|
||||
|
||||
#include <isc/lang.h>
|
||||
|
||||
ISC_LANG_BEGINDECLS
|
||||
|
||||
isc_uint64_t
|
||||
isc_meminfo_totalphys(void);
|
||||
/*%<
|
||||
* Return total available physical memory in bytes, or 0 if this cannot
|
||||
* be determined
|
||||
*/
|
||||
|
||||
ISC_LANG_ENDDECLS
|
||||
|
||||
#endif /* ISC_MEMINFO_H */
|
@ -31,15 +31,15 @@ CWARNINGS =
|
||||
# Alphabetically
|
||||
OBJS = @ISC_IPV6_O@ @ISC_PK11_API_O@ \
|
||||
app.@O@ dir.@O@ entropy.@O@ errno2result.@O@ file.@O@ \
|
||||
fsaccess.@O@ interfaceiter.@O@ keyboard.@O@ net.@O@ \
|
||||
os.@O@ resource.@O@ socket.@O@ stdio.@O@ stdtime.@O@ \
|
||||
fsaccess.@O@ interfaceiter.@O@ keyboard.@O@ meminfo.@O@ \
|
||||
net.@O@ os.@O@ resource.@O@ socket.@O@ stdio.@O@ stdtime.@O@ \
|
||||
strerror.@O@ syslog.@O@ time.@O@
|
||||
|
||||
# Alphabetically
|
||||
SRCS = @ISC_IPV6_C@ @ISC_PK11_API_C@ \
|
||||
app.c dir.c entropy.c errno2result.c file.c \
|
||||
fsaccess.c interfaceiter.c keyboard.c net.c \
|
||||
os.c resource.c socket.c stdio.c stdtime.c \
|
||||
fsaccess.c interfaceiter.c keyboard.c meminfo.c \
|
||||
net.c os.c resource.c socket.c stdio.c stdtime.c \
|
||||
strerror.c syslog.c time.c
|
||||
|
||||
SUBDIRS = include
|
||||
|
40
lib/isc/unix/meminfo.c
Normal file
40
lib/isc/unix/meminfo.c
Normal file
@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Internet Systems Consortium, Inc. ("ISC")
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
|
||||
* REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
* AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
|
||||
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
||||
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
|
||||
* OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <isc/meminfo.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/sysctl.h>
|
||||
|
||||
isc_uint64_t
|
||||
isc_meminfo_totalphys(void) {
|
||||
#if defined(CTL_HW) && (defined(HW_PHYSMEM64) || defined(HW_MEMSIZE))
|
||||
int mib[2];
|
||||
mib[0] = CTL_HW;
|
||||
#if defined(HW_MEMSIZE)
|
||||
mib[1] = HW_MEMSIZE;
|
||||
#elif defined(HW_PHYSMEM64)
|
||||
mib[1] = HW_PHYSMEM64;
|
||||
#endif
|
||||
isc_uint64_t size = 0;
|
||||
size_t len = sizeof(size);
|
||||
if (sysctl(mib, 2, &size, &len, NULL, 0) == 0)
|
||||
return (size);
|
||||
#endif
|
||||
#if defined(_SC_PHYS_PAGES) && defined(_SC_PAGESIZE)
|
||||
return ((size_t) (sysconf(_SC_PHYS_PAGES) * sysconf(_SC_PAGESIZE)));
|
||||
#endif
|
||||
return (0);
|
||||
}
|
@ -27,11 +27,11 @@ CDEFINES =
|
||||
CWARNINGS =
|
||||
|
||||
# Alphabetically
|
||||
OBJS = condition.@O@ dir.@O@ file.@O@ fsaccess.@O@ once.@O@ \
|
||||
stdtime.@O@ thread.@O@ time.@O@ @ISC_PK11_API_O@
|
||||
OBJS = condition.@O@ dir.@O@ file.@O@ meminfo.@O@ fsaccess.@O@ \
|
||||
once.@O@ stdtime.@O@ thread.@O@ time.@O@ @ISC_PK11_API_O@
|
||||
|
||||
# Alphabetically
|
||||
SRCS = condition.c dir.c file.c once.c fsaccess.c \
|
||||
SRCS = condition.c dir.c file.c meminfo.c once.c fsaccess.c \
|
||||
stdtime.c thread.c time.c @ISC_PK11_API_C@
|
||||
|
||||
SUBDIRS = include
|
||||
|
27
lib/isc/win32/meminfo.c
Normal file
27
lib/isc/win32/meminfo.c
Normal file
@ -0,0 +1,27 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Internet Systems Consortium, Inc. ("ISC")
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
|
||||
* REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
* AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
|
||||
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
||||
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
|
||||
* OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#include <isc/meminfo.h>
|
||||
|
||||
isc_uint64_t
|
||||
isc_meminfo_totalphys(void) {
|
||||
MEMORYSTATUSEX statex;
|
||||
status.dwLength = sizeof(statex);
|
||||
GlobalMemoryStatusEx(&statex);
|
||||
return ((size_t)statex.ullTotalPhys);
|
||||
}
|
@ -190,6 +190,18 @@ cfg_obj_ismap(const cfg_obj_t *obj);
|
||||
* Return true iff 'obj' is of a map type.
|
||||
*/
|
||||
|
||||
isc_boolean_t
|
||||
cfg_obj_isfixedpoint(const cfg_obj_t *obj);
|
||||
/*%<
|
||||
* Return true iff 'obj' is of a fixedpoint type.
|
||||
*/
|
||||
|
||||
isc_boolean_t
|
||||
cfg_obj_ispercentage(const cfg_obj_t *obj);
|
||||
/*%<
|
||||
* Return true iff 'obj' is of a percentage type.
|
||||
*/
|
||||
|
||||
isc_result_t
|
||||
cfg_map_get(const cfg_obj_t *mapobj, const char* name, const cfg_obj_t **obj);
|
||||
/*%<
|
||||
@ -297,6 +309,18 @@ cfg_obj_asfixedpoint(const cfg_obj_t *obj);
|
||||
* \li A 32-bit unsigned integer.
|
||||
*/
|
||||
|
||||
isc_uint32_t
|
||||
cfg_obj_aspercentage(const cfg_obj_t *obj);
|
||||
/*%<
|
||||
* Returns the value of a configuration object of percentage
|
||||
*
|
||||
* Requires:
|
||||
* \li 'obj' points to a valid configuration object of percentage type.
|
||||
*
|
||||
* Returns:
|
||||
* \li A 32-bit unsigned integer.
|
||||
*/
|
||||
|
||||
isc_boolean_t
|
||||
cfg_obj_isstring(const cfg_obj_t *obj);
|
||||
/*%<
|
||||
|
@ -267,6 +267,7 @@ LIBISCCFG_EXTERNAL_DATA extern cfg_rep_t cfg_rep_sockaddr;
|
||||
LIBISCCFG_EXTERNAL_DATA extern cfg_rep_t cfg_rep_netprefix;
|
||||
LIBISCCFG_EXTERNAL_DATA extern cfg_rep_t cfg_rep_void;
|
||||
LIBISCCFG_EXTERNAL_DATA extern cfg_rep_t cfg_rep_fixedpoint;
|
||||
LIBISCCFG_EXTERNAL_DATA extern cfg_rep_t cfg_rep_percentage;
|
||||
/*@}*/
|
||||
|
||||
/*@{*/
|
||||
@ -292,6 +293,7 @@ LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_void;
|
||||
LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_token;
|
||||
LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_unsupported;
|
||||
LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_fixedpoint;
|
||||
LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_percentage;
|
||||
/*@}*/
|
||||
|
||||
isc_result_t
|
||||
@ -455,11 +457,19 @@ void
|
||||
cfg_doc_void(cfg_printer_t *pctx, const cfg_type_t *type);
|
||||
|
||||
isc_result_t
|
||||
cfg_parse_fixedpoint(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret);
|
||||
cfg_parse_fixedpoint(cfg_parser_t *pctx, const cfg_type_t *type,
|
||||
cfg_obj_t **ret);
|
||||
|
||||
void
|
||||
cfg_print_fixedpoint(cfg_printer_t *pctx, const cfg_obj_t *obj);
|
||||
|
||||
isc_result_t
|
||||
cfg_parse_percentage(cfg_parser_t *pctx, const cfg_type_t *type,
|
||||
cfg_obj_t **ret);
|
||||
|
||||
void
|
||||
cfg_print_percentage(cfg_printer_t *pctx, const cfg_obj_t *obj);
|
||||
|
||||
isc_result_t
|
||||
cfg_parse_obj(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret);
|
||||
|
||||
|
@ -133,6 +133,7 @@ static cfg_type_t cfg_type_server;
|
||||
static cfg_type_t cfg_type_server_key_kludge;
|
||||
static cfg_type_t cfg_type_size;
|
||||
static cfg_type_t cfg_type_sizenodefault;
|
||||
static cfg_type_t cfg_type_sizeorpercent;
|
||||
static cfg_type_t cfg_type_sockaddr4wild;
|
||||
static cfg_type_t cfg_type_sockaddr6wild;
|
||||
static cfg_type_t cfg_type_statschannels;
|
||||
@ -1595,7 +1596,7 @@ view_clauses[] = {
|
||||
{ "nocookie-udp-size", &cfg_type_uint32, 0 },
|
||||
{ "nosit-udp-size", &cfg_type_uint32, CFG_CLAUSEFLAG_OBSOLETE },
|
||||
{ "max-acache-size", &cfg_type_sizenodefault, 0 },
|
||||
{ "max-cache-size", &cfg_type_sizenodefault, 0 },
|
||||
{ "max-cache-size", &cfg_type_sizeorpercent, 0 },
|
||||
{ "max-cache-ttl", &cfg_type_uint32, 0 },
|
||||
{ "max-clients-per-query", &cfg_type_uint32, 0 },
|
||||
{ "max-ncache-ttl", &cfg_type_uint32, 0 },
|
||||
@ -2065,6 +2066,56 @@ parse_sizeval(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) {
|
||||
return (result);
|
||||
}
|
||||
|
||||
static isc_result_t
|
||||
parse_sizeval_percent(cfg_parser_t *pctx, const cfg_type_t *type,
|
||||
cfg_obj_t **ret)
|
||||
{
|
||||
char *endp;
|
||||
isc_result_t result;
|
||||
cfg_obj_t *obj = NULL;
|
||||
isc_uint64_t val;
|
||||
isc_uint32_t percent;
|
||||
|
||||
UNUSED(type);
|
||||
|
||||
CHECK(cfg_gettoken(pctx, 0));
|
||||
if (pctx->token.type != isc_tokentype_string) {
|
||||
result = ISC_R_UNEXPECTEDTOKEN;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
percent = isc_string_touint64(TOKEN_STRING(pctx), &endp, 10);
|
||||
|
||||
if (*endp == '%' && *(endp+1) == 0) {
|
||||
CHECK(cfg_create_obj(pctx, &cfg_type_percentage, &obj));
|
||||
obj->value.uint32 = percent;
|
||||
*ret = obj;
|
||||
return (ISC_R_SUCCESS);
|
||||
} else {
|
||||
CHECK(parse_unitstring(TOKEN_STRING(pctx), &val));
|
||||
CHECK(cfg_create_obj(pctx, &cfg_type_uint64, &obj));
|
||||
obj->value.uint64 = val;
|
||||
*ret = obj;
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
|
||||
cleanup:
|
||||
cfg_parser_error(pctx, CFG_LOG_NEAR, "expected integer and optional unit or percent");
|
||||
return (result);
|
||||
}
|
||||
|
||||
static void
|
||||
doc_sizeval_percent(cfg_printer_t *pctx, const cfg_type_t *type) {
|
||||
|
||||
UNUSED(type);
|
||||
|
||||
cfg_print_cstr(pctx, "( ");
|
||||
cfg_doc_terminal(pctx, &cfg_type_size);
|
||||
cfg_print_cstr(pctx, " | ");
|
||||
cfg_doc_terminal(pctx, &cfg_type_percentage);
|
||||
cfg_print_cstr(pctx, " )");
|
||||
}
|
||||
|
||||
/*%
|
||||
* A size value (number + optional unit).
|
||||
*/
|
||||
@ -2097,10 +2148,42 @@ static cfg_type_t cfg_type_size = {
|
||||
*/
|
||||
static const char *sizenodefault_enums[] = { "unlimited", NULL };
|
||||
static cfg_type_t cfg_type_sizenodefault = {
|
||||
"size_no_default", parse_size, cfg_print_ustring, cfg_doc_terminal,
|
||||
"size_no_default", parse_size, cfg_print_ustring, doc_size,
|
||||
&cfg_rep_string, sizenodefault_enums
|
||||
};
|
||||
|
||||
/*%
|
||||
* A size in absolute values or percents.
|
||||
*/
|
||||
|
||||
static cfg_type_t cfg_type_sizeval_percent = {
|
||||
"sizeval_percent", parse_sizeval_percent, cfg_print_ustring,
|
||||
doc_sizeval_percent, &cfg_rep_string, NULL
|
||||
};
|
||||
|
||||
/*%
|
||||
* A size in absolute values or percents, or "unlimited", or "default"
|
||||
*/
|
||||
|
||||
static isc_result_t
|
||||
parse_size_or_percent(cfg_parser_t *pctx, const cfg_type_t *type,
|
||||
cfg_obj_t **ret)
|
||||
{
|
||||
return (parse_enum_or_other(pctx, type, &cfg_type_sizeval_percent,
|
||||
ret));
|
||||
}
|
||||
|
||||
static void
|
||||
doc_parse_size_or_percent(cfg_printer_t *pctx, const cfg_type_t *type) {
|
||||
doc_enum_or_other(pctx, type, &cfg_type_sizeval_percent);
|
||||
}
|
||||
|
||||
static const char *sizeorpercent_enums[] = { "unlimited", "default", NULL };
|
||||
static cfg_type_t cfg_type_sizeorpercent = {
|
||||
"size_or_percent", parse_size_or_percent, cfg_print_ustring,
|
||||
doc_parse_size_or_percent, &cfg_rep_string, sizeorpercent_enums
|
||||
};
|
||||
|
||||
/*%
|
||||
* optional_keyvalue
|
||||
*/
|
||||
@ -2170,7 +2253,13 @@ doc_enum_or_other(cfg_printer_t *pctx, const cfg_type_t *enumtype,
|
||||
first = ISC_FALSE;
|
||||
cfg_print_cstr(pctx, *p);
|
||||
}
|
||||
if (othertype != &cfg_type_void) {
|
||||
if (othertype == &cfg_type_sizeval_percent) {
|
||||
if (!first)
|
||||
cfg_print_cstr(pctx, " | ");
|
||||
cfg_doc_terminal(pctx, &cfg_type_sizeval);
|
||||
cfg_print_cstr(pctx, " | ");
|
||||
cfg_doc_terminal(pctx, &cfg_type_percentage);
|
||||
} else if (othertype != &cfg_type_void) {
|
||||
if (!first)
|
||||
cfg_print_cstr(pctx, " | ");
|
||||
cfg_doc_terminal(pctx, othertype);
|
||||
|
@ -123,6 +123,7 @@ cfg_rep_t cfg_rep_sockaddr = { "sockaddr", free_noop };
|
||||
cfg_rep_t cfg_rep_netprefix = { "netprefix", free_noop };
|
||||
cfg_rep_t cfg_rep_void = { "void", free_noop };
|
||||
cfg_rep_t cfg_rep_fixedpoint = { "fixedpoint", free_noop };
|
||||
cfg_rep_t cfg_rep_percentage = { "percentage", free_noop };
|
||||
|
||||
/*
|
||||
* Configuration type definitions.
|
||||
@ -650,6 +651,69 @@ cfg_type_t cfg_type_void = {
|
||||
"void", cfg_parse_void, cfg_print_void, cfg_doc_void, &cfg_rep_void,
|
||||
NULL };
|
||||
|
||||
/*
|
||||
* percentage
|
||||
*/
|
||||
isc_result_t
|
||||
cfg_parse_percentage(cfg_parser_t *pctx, const cfg_type_t *type,
|
||||
cfg_obj_t **ret)
|
||||
{
|
||||
char *endp;
|
||||
isc_result_t result;
|
||||
cfg_obj_t *obj = NULL;
|
||||
isc_uint32_t percent;
|
||||
|
||||
UNUSED(type);
|
||||
|
||||
CHECK(cfg_gettoken(pctx, 0));
|
||||
if (pctx->token.type != isc_tokentype_string) {
|
||||
cfg_parser_error(pctx, CFG_LOG_NEAR,
|
||||
"expected percentage");
|
||||
return (ISC_R_UNEXPECTEDTOKEN);
|
||||
}
|
||||
|
||||
percent = isc_string_touint64(TOKEN_STRING(pctx), &endp, 10);
|
||||
if (*endp != '%' || *(endp+1) != 0) {
|
||||
cfg_parser_error(pctx, CFG_LOG_NEAR,
|
||||
"expected percentage");
|
||||
return (ISC_R_UNEXPECTEDTOKEN);
|
||||
}
|
||||
|
||||
CHECK(cfg_create_obj(pctx, &cfg_type_percentage, &obj));
|
||||
obj->value.uint32 = percent;
|
||||
*ret = obj;
|
||||
|
||||
cleanup:
|
||||
return (result);
|
||||
}
|
||||
|
||||
void
|
||||
cfg_print_percentage(cfg_printer_t *pctx, const cfg_obj_t *obj) {
|
||||
char buf[64];
|
||||
int n;
|
||||
|
||||
n = snprintf(buf, sizeof(buf), "%u%%", obj->value.uint32);
|
||||
INSIST(n > 0 && (size_t)n < sizeof(buf));
|
||||
cfg_print_chars(pctx, buf, strlen(buf));
|
||||
}
|
||||
|
||||
isc_uint32_t
|
||||
cfg_obj_aspercentage(const cfg_obj_t *obj) {
|
||||
REQUIRE(obj != NULL && obj->type->rep == &cfg_rep_percentage);
|
||||
return (obj->value.uint32);
|
||||
}
|
||||
|
||||
cfg_type_t cfg_type_percentage = {
|
||||
"percentage", cfg_parse_percentage, cfg_print_percentage,
|
||||
cfg_doc_terminal, &cfg_rep_percentage, NULL
|
||||
};
|
||||
|
||||
isc_boolean_t
|
||||
cfg_obj_ispercentage(const cfg_obj_t *obj) {
|
||||
REQUIRE(obj != NULL);
|
||||
return (ISC_TF(obj->type->rep == &cfg_rep_percentage));
|
||||
}
|
||||
|
||||
/*
|
||||
* Fixed point
|
||||
*/
|
||||
@ -724,6 +788,12 @@ cfg_type_t cfg_type_fixedpoint = {
|
||||
cfg_doc_terminal, &cfg_rep_fixedpoint, NULL
|
||||
};
|
||||
|
||||
isc_boolean_t
|
||||
cfg_obj_isfixedpoint(const cfg_obj_t *obj) {
|
||||
REQUIRE(obj != NULL);
|
||||
return (ISC_TF(obj->type->rep == &cfg_rep_fixedpoint));
|
||||
}
|
||||
|
||||
/*
|
||||
* uint32
|
||||
*/
|
||||
|
Loading…
x
Reference in New Issue
Block a user