Annotation of embedaddon/ntp/lib/isc/unix/resource.c, revision 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>