4 * Copyright (C) 2004, 2007-2009 Internet Systems Consortium, Inc. ("ISC")
5 * Copyright (C) 2000, 2001 Internet Software Consortium.
7 * Permission to use, copy, modify, and/or distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
11 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
12 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
13 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
14 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
15 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
16 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17 * PERFORMANCE OF THIS SOFTWARE.
20 /* Id: resource.c,v 1.21.66.2 2009/02/13 23:47:39 tbox Exp */
24 #include <sys/types.h>
25 #include <sys/time.h> /* Required on some systems for <sys/resource.h>. */
26 #include <sys/resource.h>
28 #include <isc/platform.h>
29 #include <isc/resource.h>
30 #include <isc/result.h>
34 #include <linux/fs.h> /* To get the large NR_OPEN. */
37 #if defined(__hpux) && defined(HAVE_SYS_DYNTUNE_H)
38 #include <sys/dyntune.h>
41 #include "errno2result.h"
44 resource2rlim(isc_resource_t resource
, int *rlim_resource
) {
45 isc_result_t result
= ISC_R_SUCCESS
;
48 case isc_resource_coresize
:
49 *rlim_resource
= RLIMIT_CORE
;
51 case isc_resource_cputime
:
52 *rlim_resource
= RLIMIT_CPU
;
54 case isc_resource_datasize
:
55 *rlim_resource
= RLIMIT_DATA
;
57 case isc_resource_filesize
:
58 *rlim_resource
= RLIMIT_FSIZE
;
60 case isc_resource_lockedmemory
:
62 *rlim_resource
= RLIMIT_MEMLOCK
;
64 result
= ISC_R_NOTIMPLEMENTED
;
67 case isc_resource_openfiles
:
69 *rlim_resource
= RLIMIT_NOFILE
;
71 result
= ISC_R_NOTIMPLEMENTED
;
74 case isc_resource_processes
:
76 *rlim_resource
= RLIMIT_NPROC
;
78 result
= ISC_R_NOTIMPLEMENTED
;
81 case isc_resource_residentsize
:
83 *rlim_resource
= RLIMIT_RSS
;
85 result
= ISC_R_NOTIMPLEMENTED
;
88 case isc_resource_stacksize
:
89 *rlim_resource
= RLIMIT_STACK
;
93 * This test is not very robust if isc_resource_t
94 * changes, but generates a clear assertion message.
96 REQUIRE(resource
>= isc_resource_coresize
&&
97 resource
<= isc_resource_stacksize
);
107 isc_resource_setlimit(isc_resource_t resource
, isc_resourcevalue_t value
) {
109 ISC_PLATFORM_RLIMITTYPE rlim_value
;
114 result
= resource2rlim(resource
, &unixresource
);
115 if (result
!= ISC_R_SUCCESS
)
118 if (value
== ISC_RESOURCE_UNLIMITED
)
119 rlim_value
= RLIM_INFINITY
;
123 * isc_resourcevalue_t was chosen as an unsigned 64 bit
124 * integer so that it could contain the maximum range of
125 * reasonable values. Unfortunately, this exceeds the typical
126 * range on Unix systems. Ensure the range of
127 * ISC_PLATFORM_RLIMITTYPE is not overflowed.
129 isc_resourcevalue_t rlim_max
;
130 isc_boolean_t rlim_t_is_signed
=
131 ISC_TF(((double)(ISC_PLATFORM_RLIMITTYPE
)-1) < 0);
133 if (rlim_t_is_signed
)
134 rlim_max
= ~((ISC_PLATFORM_RLIMITTYPE
)1 <<
135 (sizeof(ISC_PLATFORM_RLIMITTYPE
) * 8 - 1));
137 rlim_max
= (ISC_PLATFORM_RLIMITTYPE
)-1;
139 if (value
> rlim_max
)
145 rl
.rlim_cur
= rl
.rlim_max
= rlim_value
;
146 unixresult
= setrlimit(unixresource
, &rl
);
149 return (ISC_R_SUCCESS
);
151 #if defined(OPEN_MAX) && defined(__APPLE__)
153 * The Darwin kernel doesn't accept RLIM_INFINITY for rlim_cur; the
154 * maximum possible value is OPEN_MAX. BIND8 used to use
155 * sysconf(_SC_OPEN_MAX) for such a case, but this value is much
156 * smaller than OPEN_MAX and is not really effective.
158 if (resource
== isc_resource_openfiles
&& rlim_value
== RLIM_INFINITY
) {
159 rl
.rlim_cur
= OPEN_MAX
;
160 unixresult
= setrlimit(unixresource
, &rl
);
162 return (ISC_R_SUCCESS
);
164 #elif defined(__linux__)
166 #define NR_OPEN (1024*1024)
170 * Some Linux kernels don't accept RLIM_INFINIT; the maximum
171 * possible value is the NR_OPEN defined in linux/fs.h.
173 if (resource
== isc_resource_openfiles
&& rlim_value
== RLIM_INFINITY
) {
174 rl
.rlim_cur
= rl
.rlim_max
= NR_OPEN
;
175 unixresult
= setrlimit(unixresource
, &rl
);
177 return (ISC_R_SUCCESS
);
179 #elif defined(__hpux) && defined(HAVE_SYS_DYNTUNE_H)
180 if (resource
== isc_resource_openfiles
&& rlim_value
== RLIM_INFINITY
) {
182 if (gettune("maxfiles_lim", &maxfiles
) == 0) {
183 rl
.rlim_cur
= rl
.rlim_max
= maxfiles
;
184 unixresult
= setrlimit(unixresource
, &rl
);
186 return (ISC_R_SUCCESS
);
190 if (resource
== isc_resource_openfiles
&& rlim_value
== RLIM_INFINITY
) {
191 if (getrlimit(unixresource
, &rl
) == 0) {
192 rl
.rlim_cur
= rl
.rlim_max
;
193 unixresult
= setrlimit(unixresource
, &rl
);
195 return (ISC_R_SUCCESS
);
198 return (isc__errno2result(errno
));
202 isc_resource_getlimit(isc_resource_t resource
, isc_resourcevalue_t
*value
) {
208 result
= resource2rlim(resource
, &unixresource
);
209 if (result
== ISC_R_SUCCESS
) {
210 unixresult
= getrlimit(unixresource
, &rl
);
211 INSIST(unixresult
== 0);
212 *value
= rl
.rlim_max
;
219 isc_resource_getcurlimit(isc_resource_t resource
, isc_resourcevalue_t
*value
) {
225 result
= resource2rlim(resource
, &unixresource
);
226 if (result
== ISC_R_SUCCESS
) {
227 unixresult
= getrlimit(unixresource
, &rl
);
228 INSIST(unixresult
== 0);
229 *value
= rl
.rlim_cur
;