Annotation of embedaddon/ntp/lib/isc/unix/resource.c, revision 1.1.1.1
1.1 misho 1: /*
2: * Copyright (C) 2004, 2007-2009 Internet Systems Consortium, Inc. ("ISC")
3: * Copyright (C) 2000, 2001 Internet Software Consortium.
4: *
5: * Permission to use, copy, modify, and/or distribute this software for any
6: * purpose with or without fee is hereby granted, provided that the above
7: * copyright notice and this permission notice appear in all copies.
8: *
9: * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
10: * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
11: * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
12: * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
13: * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
14: * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
15: * PERFORMANCE OF THIS SOFTWARE.
16: */
17:
18: /* $Id: resource.c,v 1.21.66.2 2009/02/13 23:47:39 tbox Exp $ */
19:
20: #include <config.h>
21:
22: #include <sys/types.h>
23: #include <sys/time.h> /* Required on some systems for <sys/resource.h>. */
24: #include <sys/resource.h>
25:
26: #include <isc/platform.h>
27: #include <isc/resource.h>
28: #include <isc/result.h>
29: #include <isc/util.h>
30:
31: #ifdef __linux__
32: #include <linux/fs.h> /* To get the large NR_OPEN. */
33: #endif
34:
35: #if defined(__hpux) && defined(HAVE_SYS_DYNTUNE_H)
36: #include <sys/dyntune.h>
37: #endif
38:
39: #include "errno2result.h"
40:
41: static isc_result_t
42: resource2rlim(isc_resource_t resource, int *rlim_resource) {
43: isc_result_t result = ISC_R_SUCCESS;
44:
45: switch (resource) {
46: case isc_resource_coresize:
47: *rlim_resource = RLIMIT_CORE;
48: break;
49: case isc_resource_cputime:
50: *rlim_resource = RLIMIT_CPU;
51: break;
52: case isc_resource_datasize:
53: *rlim_resource = RLIMIT_DATA;
54: break;
55: case isc_resource_filesize:
56: *rlim_resource = RLIMIT_FSIZE;
57: break;
58: case isc_resource_lockedmemory:
59: #ifdef RLIMIT_MEMLOCK
60: *rlim_resource = RLIMIT_MEMLOCK;
61: #else
62: result = ISC_R_NOTIMPLEMENTED;
63: #endif
64: break;
65: case isc_resource_openfiles:
66: #ifdef RLIMIT_NOFILE
67: *rlim_resource = RLIMIT_NOFILE;
68: #else
69: result = ISC_R_NOTIMPLEMENTED;
70: #endif
71: break;
72: case isc_resource_processes:
73: #ifdef RLIMIT_NPROC
74: *rlim_resource = RLIMIT_NPROC;
75: #else
76: result = ISC_R_NOTIMPLEMENTED;
77: #endif
78: break;
79: case isc_resource_residentsize:
80: #ifdef RLIMIT_RSS
81: *rlim_resource = RLIMIT_RSS;
82: #else
83: result = ISC_R_NOTIMPLEMENTED;
84: #endif
85: break;
86: case isc_resource_stacksize:
87: *rlim_resource = RLIMIT_STACK;
88: break;
89: default:
90: /*
91: * This test is not very robust if isc_resource_t
92: * changes, but generates a clear assertion message.
93: */
94: REQUIRE(resource >= isc_resource_coresize &&
95: resource <= isc_resource_stacksize);
96:
97: result = ISC_R_RANGE;
98: break;
99: }
100:
101: return (result);
102: }
103:
104: isc_result_t
105: isc_resource_setlimit(isc_resource_t resource, isc_resourcevalue_t value) {
106: struct rlimit rl;
107: ISC_PLATFORM_RLIMITTYPE rlim_value;
108: int unixresult;
109: int unixresource;
110: isc_result_t result;
111:
112: result = resource2rlim(resource, &unixresource);
113: if (result != ISC_R_SUCCESS)
114: return (result);
115:
116: if (value == ISC_RESOURCE_UNLIMITED)
117: rlim_value = RLIM_INFINITY;
118:
119: else {
120: /*
121: * isc_resourcevalue_t was chosen as an unsigned 64 bit
122: * integer so that it could contain the maximum range of
123: * reasonable values. Unfortunately, this exceeds the typical
124: * range on Unix systems. Ensure the range of
125: * ISC_PLATFORM_RLIMITTYPE is not overflowed.
126: */
127: isc_resourcevalue_t rlim_max;
128: isc_boolean_t rlim_t_is_signed =
129: ISC_TF(((double)(ISC_PLATFORM_RLIMITTYPE)-1) < 0);
130:
131: if (rlim_t_is_signed)
132: rlim_max = ~((ISC_PLATFORM_RLIMITTYPE)1 <<
133: (sizeof(ISC_PLATFORM_RLIMITTYPE) * 8 - 1));
134: else
135: rlim_max = (ISC_PLATFORM_RLIMITTYPE)-1;
136:
137: if (value > rlim_max)
138: value = rlim_max;
139:
140: rlim_value = value;
141: }
142:
143: rl.rlim_cur = rl.rlim_max = rlim_value;
144: unixresult = setrlimit(unixresource, &rl);
145:
146: if (unixresult == 0)
147: return (ISC_R_SUCCESS);
148:
149: #if defined(OPEN_MAX) && defined(__APPLE__)
150: /*
151: * The Darwin kernel doesn't accept RLIM_INFINITY for rlim_cur; the
152: * maximum possible value is OPEN_MAX. BIND8 used to use
153: * sysconf(_SC_OPEN_MAX) for such a case, but this value is much
154: * smaller than OPEN_MAX and is not really effective.
155: */
156: if (resource == isc_resource_openfiles && rlim_value == RLIM_INFINITY) {
157: rl.rlim_cur = OPEN_MAX;
158: unixresult = setrlimit(unixresource, &rl);
159: if (unixresult == 0)
160: return (ISC_R_SUCCESS);
161: }
162: #elif defined(__linux__)
163: #ifndef NR_OPEN
164: #define NR_OPEN (1024*1024)
165: #endif
166:
167: /*
168: * Some Linux kernels don't accept RLIM_INFINIT; the maximum
169: * possible value is the NR_OPEN defined in linux/fs.h.
170: */
171: if (resource == isc_resource_openfiles && rlim_value == RLIM_INFINITY) {
172: rl.rlim_cur = rl.rlim_max = NR_OPEN;
173: unixresult = setrlimit(unixresource, &rl);
174: if (unixresult == 0)
175: return (ISC_R_SUCCESS);
176: }
177: #elif defined(__hpux) && defined(HAVE_SYS_DYNTUNE_H)
178: if (resource == isc_resource_openfiles && rlim_value == RLIM_INFINITY) {
179: uint64_t maxfiles;
180: if (gettune("maxfiles_lim", &maxfiles) == 0) {
181: rl.rlim_cur = rl.rlim_max = maxfiles;
182: unixresult = setrlimit(unixresource, &rl);
183: if (unixresult == 0)
184: return (ISC_R_SUCCESS);
185: }
186: }
187: #endif
188: if (resource == isc_resource_openfiles && rlim_value == RLIM_INFINITY) {
189: if (getrlimit(unixresource, &rl) == 0) {
190: rl.rlim_cur = rl.rlim_max;
191: unixresult = setrlimit(unixresource, &rl);
192: if (unixresult == 0)
193: return (ISC_R_SUCCESS);
194: }
195: }
196: return (isc__errno2result(errno));
197: }
198:
199: isc_result_t
200: isc_resource_getlimit(isc_resource_t resource, isc_resourcevalue_t *value) {
201: int unixresult;
202: int unixresource;
203: struct rlimit rl;
204: isc_result_t result;
205:
206: result = resource2rlim(resource, &unixresource);
207: if (result == ISC_R_SUCCESS) {
208: unixresult = getrlimit(unixresource, &rl);
209: INSIST(unixresult == 0);
210: *value = rl.rlim_max;
211: }
212:
213: return (result);
214: }
215:
216: isc_result_t
217: isc_resource_getcurlimit(isc_resource_t resource, isc_resourcevalue_t *value) {
218: int unixresult;
219: int unixresource;
220: struct rlimit rl;
221: isc_result_t result;
222:
223: result = resource2rlim(resource, &unixresource);
224: if (result == ISC_R_SUCCESS) {
225: unixresult = getrlimit(unixresource, &rl);
226: INSIST(unixresult == 0);
227: *value = rl.rlim_cur;
228: }
229:
230: return (result);
231: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>