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>