|
Packit Service |
ae04f2 |
/*
|
|
Packit Service |
ae04f2 |
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
|
Packit Service |
ae04f2 |
*
|
|
Packit Service |
ae04f2 |
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
Packit Service |
ae04f2 |
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
Packit Service |
ae04f2 |
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
Packit Service |
ae04f2 |
*
|
|
Packit Service |
ae04f2 |
* See the COPYRIGHT file distributed with this work for additional
|
|
Packit Service |
ae04f2 |
* information regarding copyright ownership.
|
|
Packit Service |
ae04f2 |
*/
|
|
Packit Service |
ae04f2 |
|
|
Packit Service |
ae04f2 |
|
|
Packit Service |
ae04f2 |
#include <config.h>
|
|
Packit Service |
ae04f2 |
|
|
Packit Service |
ae04f2 |
#include <inttypes.h>
|
|
Packit Service |
ae04f2 |
#include <stdbool.h>
|
|
Packit Service |
ae04f2 |
|
|
Packit Service |
ae04f2 |
#include <sys/types.h>
|
|
Packit Service |
ae04f2 |
#include <sys/time.h> /* Required on some systems for <sys/resource.h>. */
|
|
Packit Service |
ae04f2 |
#include <sys/resource.h>
|
|
Packit Service |
ae04f2 |
|
|
Packit Service |
ae04f2 |
#include <isc/platform.h>
|
|
Packit Service |
ae04f2 |
#include <isc/resource.h>
|
|
Packit Service |
ae04f2 |
#include <isc/result.h>
|
|
Packit Service |
ae04f2 |
#include <isc/util.h>
|
|
Packit Service |
ae04f2 |
|
|
Packit Service |
ae04f2 |
#ifdef __linux__
|
|
Packit Service |
ae04f2 |
#include <linux/fs.h> /* To get the large NR_OPEN. */
|
|
Packit Service |
ae04f2 |
#endif
|
|
Packit Service |
ae04f2 |
|
|
Packit Service |
ae04f2 |
#if defined(__hpux) && defined(HAVE_SYS_DYNTUNE_H)
|
|
Packit Service |
ae04f2 |
#include <sys/dyntune.h>
|
|
Packit Service |
ae04f2 |
#endif
|
|
Packit Service |
ae04f2 |
|
|
Packit Service |
ae04f2 |
#include "errno2result.h"
|
|
Packit Service |
ae04f2 |
|
|
Packit Service |
ae04f2 |
static isc_result_t
|
|
Packit Service |
ae04f2 |
resource2rlim(isc_resource_t resource, int *rlim_resource) {
|
|
Packit Service |
ae04f2 |
isc_result_t result = ISC_R_SUCCESS;
|
|
Packit Service |
ae04f2 |
|
|
Packit Service |
ae04f2 |
switch (resource) {
|
|
Packit Service |
ae04f2 |
case isc_resource_coresize:
|
|
Packit Service |
ae04f2 |
*rlim_resource = RLIMIT_CORE;
|
|
Packit Service |
ae04f2 |
break;
|
|
Packit Service |
ae04f2 |
case isc_resource_cputime:
|
|
Packit Service |
ae04f2 |
*rlim_resource = RLIMIT_CPU;
|
|
Packit Service |
ae04f2 |
break;
|
|
Packit Service |
ae04f2 |
case isc_resource_datasize:
|
|
Packit Service |
ae04f2 |
*rlim_resource = RLIMIT_DATA;
|
|
Packit Service |
ae04f2 |
break;
|
|
Packit Service |
ae04f2 |
case isc_resource_filesize:
|
|
Packit Service |
ae04f2 |
*rlim_resource = RLIMIT_FSIZE;
|
|
Packit Service |
ae04f2 |
break;
|
|
Packit Service |
ae04f2 |
case isc_resource_lockedmemory:
|
|
Packit Service |
ae04f2 |
#ifdef RLIMIT_MEMLOCK
|
|
Packit Service |
ae04f2 |
*rlim_resource = RLIMIT_MEMLOCK;
|
|
Packit Service |
ae04f2 |
#else
|
|
Packit Service |
ae04f2 |
result = ISC_R_NOTIMPLEMENTED;
|
|
Packit Service |
ae04f2 |
#endif
|
|
Packit Service |
ae04f2 |
break;
|
|
Packit Service |
ae04f2 |
case isc_resource_openfiles:
|
|
Packit Service |
ae04f2 |
#ifdef RLIMIT_NOFILE
|
|
Packit Service |
ae04f2 |
*rlim_resource = RLIMIT_NOFILE;
|
|
Packit Service |
ae04f2 |
#else
|
|
Packit Service |
ae04f2 |
result = ISC_R_NOTIMPLEMENTED;
|
|
Packit Service |
ae04f2 |
#endif
|
|
Packit Service |
ae04f2 |
break;
|
|
Packit Service |
ae04f2 |
case isc_resource_processes:
|
|
Packit Service |
ae04f2 |
#ifdef RLIMIT_NPROC
|
|
Packit Service |
ae04f2 |
*rlim_resource = RLIMIT_NPROC;
|
|
Packit Service |
ae04f2 |
#else
|
|
Packit Service |
ae04f2 |
result = ISC_R_NOTIMPLEMENTED;
|
|
Packit Service |
ae04f2 |
#endif
|
|
Packit Service |
ae04f2 |
break;
|
|
Packit Service |
ae04f2 |
case isc_resource_residentsize:
|
|
Packit Service |
ae04f2 |
#ifdef RLIMIT_RSS
|
|
Packit Service |
ae04f2 |
*rlim_resource = RLIMIT_RSS;
|
|
Packit Service |
ae04f2 |
#else
|
|
Packit Service |
ae04f2 |
result = ISC_R_NOTIMPLEMENTED;
|
|
Packit Service |
ae04f2 |
#endif
|
|
Packit Service |
ae04f2 |
break;
|
|
Packit Service |
ae04f2 |
case isc_resource_stacksize:
|
|
Packit Service |
ae04f2 |
*rlim_resource = RLIMIT_STACK;
|
|
Packit Service |
ae04f2 |
break;
|
|
Packit Service |
ae04f2 |
default:
|
|
Packit Service |
ae04f2 |
/*
|
|
Packit Service |
ae04f2 |
* This test is not very robust if isc_resource_t
|
|
Packit Service |
ae04f2 |
* changes, but generates a clear assertion message.
|
|
Packit Service |
ae04f2 |
*/
|
|
Packit Service |
ae04f2 |
REQUIRE(resource >= isc_resource_coresize &&
|
|
Packit Service |
ae04f2 |
resource <= isc_resource_stacksize);
|
|
Packit Service |
ae04f2 |
|
|
Packit Service |
ae04f2 |
result = ISC_R_RANGE;
|
|
Packit Service |
ae04f2 |
break;
|
|
Packit Service |
ae04f2 |
}
|
|
Packit Service |
ae04f2 |
|
|
Packit Service |
ae04f2 |
return (result);
|
|
Packit Service |
ae04f2 |
}
|
|
Packit Service |
ae04f2 |
|
|
Packit Service |
ae04f2 |
isc_result_t
|
|
Packit Service |
ae04f2 |
isc_resource_setlimit(isc_resource_t resource, isc_resourcevalue_t value) {
|
|
Packit Service |
ae04f2 |
struct rlimit rl;
|
|
Packit Service |
ae04f2 |
ISC_PLATFORM_RLIMITTYPE rlim_value;
|
|
Packit Service |
ae04f2 |
int unixresult;
|
|
Packit Service |
ae04f2 |
int unixresource;
|
|
Packit Service |
ae04f2 |
isc_result_t result;
|
|
Packit Service |
ae04f2 |
|
|
Packit Service |
ae04f2 |
result = resource2rlim(resource, &unixresource);
|
|
Packit Service |
ae04f2 |
if (result != ISC_R_SUCCESS)
|
|
Packit Service |
ae04f2 |
return (result);
|
|
Packit Service |
ae04f2 |
|
|
Packit Service |
ae04f2 |
if (value == ISC_RESOURCE_UNLIMITED)
|
|
Packit Service |
ae04f2 |
rlim_value = RLIM_INFINITY;
|
|
Packit Service |
ae04f2 |
|
|
Packit Service |
ae04f2 |
else {
|
|
Packit Service |
ae04f2 |
/*
|
|
Packit Service |
ae04f2 |
* isc_resourcevalue_t was chosen as an unsigned 64 bit
|
|
Packit Service |
ae04f2 |
* integer so that it could contain the maximum range of
|
|
Packit Service |
ae04f2 |
* reasonable values. Unfortunately, this exceeds the typical
|
|
Packit Service |
ae04f2 |
* range on Unix systems. Ensure the range of
|
|
Packit Service |
ae04f2 |
* ISC_PLATFORM_RLIMITTYPE is not overflowed.
|
|
Packit Service |
ae04f2 |
*/
|
|
Packit Service |
ae04f2 |
isc_resourcevalue_t rlim_max;
|
|
Packit Service |
ae04f2 |
bool rlim_t_is_signed =
|
|
Packit Service |
ae04f2 |
(((double)(ISC_PLATFORM_RLIMITTYPE)-1) < 0);
|
|
Packit Service |
ae04f2 |
|
|
Packit Service |
ae04f2 |
if (rlim_t_is_signed)
|
|
Packit Service |
ae04f2 |
rlim_max = ~((ISC_PLATFORM_RLIMITTYPE)1 <<
|
|
Packit Service |
ae04f2 |
(sizeof(ISC_PLATFORM_RLIMITTYPE) * 8 - 1));
|
|
Packit Service |
ae04f2 |
else
|
|
Packit Service |
ae04f2 |
rlim_max = (ISC_PLATFORM_RLIMITTYPE)-1;
|
|
Packit Service |
ae04f2 |
|
|
Packit Service |
ae04f2 |
if (value > rlim_max)
|
|
Packit Service |
ae04f2 |
value = rlim_max;
|
|
Packit Service |
ae04f2 |
|
|
Packit Service |
ae04f2 |
rlim_value = value;
|
|
Packit Service |
ae04f2 |
}
|
|
Packit Service |
ae04f2 |
|
|
Packit Service |
ae04f2 |
rl.rlim_cur = rl.rlim_max = rlim_value;
|
|
Packit Service |
ae04f2 |
unixresult = setrlimit(unixresource, &rl);
|
|
Packit Service |
ae04f2 |
|
|
Packit Service |
ae04f2 |
if (unixresult == 0)
|
|
Packit Service |
ae04f2 |
return (ISC_R_SUCCESS);
|
|
Packit Service |
ae04f2 |
|
|
Packit Service |
ae04f2 |
#if defined(OPEN_MAX) && defined(__APPLE__)
|
|
Packit Service |
ae04f2 |
/*
|
|
Packit Service |
ae04f2 |
* The Darwin kernel doesn't accept RLIM_INFINITY for rlim_cur; the
|
|
Packit Service |
ae04f2 |
* maximum possible value is OPEN_MAX. BIND8 used to use
|
|
Packit Service |
ae04f2 |
* sysconf(_SC_OPEN_MAX) for such a case, but this value is much
|
|
Packit Service |
ae04f2 |
* smaller than OPEN_MAX and is not really effective.
|
|
Packit Service |
ae04f2 |
*/
|
|
Packit Service |
ae04f2 |
if (resource == isc_resource_openfiles && rlim_value == RLIM_INFINITY) {
|
|
Packit Service |
ae04f2 |
rl.rlim_cur = OPEN_MAX;
|
|
Packit Service |
ae04f2 |
unixresult = setrlimit(unixresource, &rl);
|
|
Packit Service |
ae04f2 |
if (unixresult == 0)
|
|
Packit Service |
ae04f2 |
return (ISC_R_SUCCESS);
|
|
Packit Service |
ae04f2 |
}
|
|
Packit Service |
ae04f2 |
#elif defined(__linux__)
|
|
Packit Service |
ae04f2 |
#ifndef NR_OPEN
|
|
Packit Service |
ae04f2 |
#define NR_OPEN (1024*1024)
|
|
Packit Service |
ae04f2 |
#endif
|
|
Packit Service |
ae04f2 |
|
|
Packit Service |
ae04f2 |
/*
|
|
Packit Service |
ae04f2 |
* Some Linux kernels don't accept RLIM_INFINIT; the maximum
|
|
Packit Service |
ae04f2 |
* possible value is the NR_OPEN defined in linux/fs.h.
|
|
Packit Service |
ae04f2 |
*/
|
|
Packit Service |
ae04f2 |
if (resource == isc_resource_openfiles && rlim_value == RLIM_INFINITY) {
|
|
Packit Service |
ae04f2 |
rl.rlim_cur = rl.rlim_max = NR_OPEN;
|
|
Packit Service |
ae04f2 |
unixresult = setrlimit(unixresource, &rl);
|
|
Packit Service |
ae04f2 |
if (unixresult == 0)
|
|
Packit Service |
ae04f2 |
return (ISC_R_SUCCESS);
|
|
Packit Service |
ae04f2 |
}
|
|
Packit Service |
ae04f2 |
#elif defined(__hpux) && defined(HAVE_SYS_DYNTUNE_H)
|
|
Packit Service |
ae04f2 |
if (resource == isc_resource_openfiles && rlim_value == RLIM_INFINITY) {
|
|
Packit Service |
ae04f2 |
uint64_t maxfiles;
|
|
Packit Service |
ae04f2 |
if (gettune("maxfiles_lim", &maxfiles) == 0) {
|
|
Packit Service |
ae04f2 |
rl.rlim_cur = rl.rlim_max = maxfiles;
|
|
Packit Service |
ae04f2 |
unixresult = setrlimit(unixresource, &rl);
|
|
Packit Service |
ae04f2 |
if (unixresult == 0)
|
|
Packit Service |
ae04f2 |
return (ISC_R_SUCCESS);
|
|
Packit Service |
ae04f2 |
}
|
|
Packit Service |
ae04f2 |
}
|
|
Packit Service |
ae04f2 |
#endif
|
|
Packit Service |
ae04f2 |
if (resource == isc_resource_openfiles && rlim_value == RLIM_INFINITY) {
|
|
Packit Service |
ae04f2 |
if (getrlimit(unixresource, &rl) == 0) {
|
|
Packit Service |
ae04f2 |
rl.rlim_cur = rl.rlim_max;
|
|
Packit Service |
ae04f2 |
unixresult = setrlimit(unixresource, &rl);
|
|
Packit Service |
ae04f2 |
if (unixresult == 0)
|
|
Packit Service |
ae04f2 |
return (ISC_R_SUCCESS);
|
|
Packit Service |
ae04f2 |
}
|
|
Packit Service |
ae04f2 |
}
|
|
Packit Service |
ae04f2 |
return (isc__errno2result(errno));
|
|
Packit Service |
ae04f2 |
}
|
|
Packit Service |
ae04f2 |
|
|
Packit Service |
ae04f2 |
isc_result_t
|
|
Packit Service |
ae04f2 |
isc_resource_getlimit(isc_resource_t resource, isc_resourcevalue_t *value) {
|
|
Packit Service |
ae04f2 |
int unixresource;
|
|
Packit Service |
ae04f2 |
struct rlimit rl;
|
|
Packit Service |
ae04f2 |
isc_result_t result;
|
|
Packit Service |
ae04f2 |
|
|
Packit Service |
ae04f2 |
result = resource2rlim(resource, &unixresource);
|
|
Packit Service |
ae04f2 |
if (result != ISC_R_SUCCESS) {
|
|
Packit Service |
ae04f2 |
return (result);
|
|
Packit Service |
ae04f2 |
}
|
|
Packit Service |
ae04f2 |
|
|
Packit Service |
ae04f2 |
if (getrlimit(unixresource, &rl) != 0) {
|
|
Packit Service |
ae04f2 |
return (isc__errno2result(errno));
|
|
Packit Service |
ae04f2 |
}
|
|
Packit Service |
ae04f2 |
|
|
Packit Service |
ae04f2 |
*value = rl.rlim_max;
|
|
Packit Service |
ae04f2 |
return (ISC_R_SUCCESS);
|
|
Packit Service |
ae04f2 |
}
|
|
Packit Service |
ae04f2 |
|
|
Packit Service |
ae04f2 |
isc_result_t
|
|
Packit Service |
ae04f2 |
isc_resource_getcurlimit(isc_resource_t resource, isc_resourcevalue_t *value) {
|
|
Packit Service |
ae04f2 |
int unixresource;
|
|
Packit Service |
ae04f2 |
struct rlimit rl;
|
|
Packit Service |
ae04f2 |
isc_result_t result;
|
|
Packit Service |
ae04f2 |
|
|
Packit Service |
ae04f2 |
result = resource2rlim(resource, &unixresource);
|
|
Packit Service |
ae04f2 |
if (result != ISC_R_SUCCESS) {
|
|
Packit Service |
ae04f2 |
return (result);
|
|
Packit Service |
ae04f2 |
}
|
|
Packit Service |
ae04f2 |
|
|
Packit Service |
ae04f2 |
if (getrlimit(unixresource, &rl) != 0) {
|
|
Packit Service |
ae04f2 |
return (isc__errno2result(errno));
|
|
Packit Service |
ae04f2 |
}
|
|
Packit Service |
ae04f2 |
|
|
Packit Service |
ae04f2 |
*value = rl.rlim_cur;
|
|
Packit Service |
ae04f2 |
return (ISC_R_SUCCESS);
|
|
Packit Service |
ae04f2 |
}
|