00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include <config.h>
00021
00022 #include <sys/types.h>
00023 #include <sys/time.h>
00024 #include <sys/resource.h>
00025
00026 #include <isc/platform.h>
00027 #include <isc/resource.h>
00028 #include <isc/result.h>
00029 #include <isc/util.h>
00030
00031 #ifdef __linux__
00032 #include <linux/fs.h>
00033 #endif
00034
00035 #if defined(__hpux) && defined(HAVE_SYS_DYNTUNE_H)
00036 #include <sys/dyntune.h>
00037 #endif
00038
00039 #include "errno2result.h"
00040
00041 static isc_result_t
00042 resource2rlim(isc_resource_t resource, int *rlim_resource) {
00043 isc_result_t result = ISC_R_SUCCESS;
00044
00045 switch (resource) {
00046 case isc_resource_coresize:
00047 *rlim_resource = RLIMIT_CORE;
00048 break;
00049 case isc_resource_cputime:
00050 *rlim_resource = RLIMIT_CPU;
00051 break;
00052 case isc_resource_datasize:
00053 *rlim_resource = RLIMIT_DATA;
00054 break;
00055 case isc_resource_filesize:
00056 *rlim_resource = RLIMIT_FSIZE;
00057 break;
00058 case isc_resource_lockedmemory:
00059 #ifdef RLIMIT_MEMLOCK
00060 *rlim_resource = RLIMIT_MEMLOCK;
00061 #else
00062 result = ISC_R_NOTIMPLEMENTED;
00063 #endif
00064 break;
00065 case isc_resource_openfiles:
00066 #ifdef RLIMIT_NOFILE
00067 *rlim_resource = RLIMIT_NOFILE;
00068 #else
00069 result = ISC_R_NOTIMPLEMENTED;
00070 #endif
00071 break;
00072 case isc_resource_processes:
00073 #ifdef RLIMIT_NPROC
00074 *rlim_resource = RLIMIT_NPROC;
00075 #else
00076 result = ISC_R_NOTIMPLEMENTED;
00077 #endif
00078 break;
00079 case isc_resource_residentsize:
00080 #ifdef RLIMIT_RSS
00081 *rlim_resource = RLIMIT_RSS;
00082 #else
00083 result = ISC_R_NOTIMPLEMENTED;
00084 #endif
00085 break;
00086 case isc_resource_stacksize:
00087 *rlim_resource = RLIMIT_STACK;
00088 break;
00089 default:
00090
00091
00092
00093
00094 REQUIRE(resource >= isc_resource_coresize &&
00095 resource <= isc_resource_stacksize);
00096
00097 result = ISC_R_RANGE;
00098 break;
00099 }
00100
00101 return (result);
00102 }
00103
00104 isc_result_t
00105 isc_resource_setlimit(isc_resource_t resource, isc_resourcevalue_t value) {
00106 struct rlimit rl;
00107 ISC_PLATFORM_RLIMITTYPE rlim_value;
00108 int unixresult;
00109 int unixresource;
00110 isc_result_t result;
00111
00112 result = resource2rlim(resource, &unixresource);
00113 if (result != ISC_R_SUCCESS)
00114 return (result);
00115
00116 if (value == ISC_RESOURCE_UNLIMITED)
00117 rlim_value = RLIM_INFINITY;
00118
00119 else {
00120
00121
00122
00123
00124
00125
00126
00127 isc_resourcevalue_t rlim_max;
00128 isc_boolean_t rlim_t_is_signed =
00129 ISC_TF(((double)(ISC_PLATFORM_RLIMITTYPE)-1) < 0);
00130
00131 if (rlim_t_is_signed)
00132 rlim_max = ~((ISC_PLATFORM_RLIMITTYPE)1 <<
00133 (sizeof(ISC_PLATFORM_RLIMITTYPE) * 8 - 1));
00134 else
00135 rlim_max = (ISC_PLATFORM_RLIMITTYPE)-1;
00136
00137 if (value > rlim_max)
00138 value = rlim_max;
00139
00140 rlim_value = value;
00141 }
00142
00143 rl.rlim_cur = rl.rlim_max = rlim_value;
00144 unixresult = setrlimit(unixresource, &rl);
00145
00146 if (unixresult == 0)
00147 return (ISC_R_SUCCESS);
00148
00149 #if defined(OPEN_MAX) && defined(__APPLE__)
00150
00151
00152
00153
00154
00155
00156 if (resource == isc_resource_openfiles && rlim_value == RLIM_INFINITY) {
00157 rl.rlim_cur = OPEN_MAX;
00158 unixresult = setrlimit(unixresource, &rl);
00159 if (unixresult == 0)
00160 return (ISC_R_SUCCESS);
00161 }
00162 #elif defined(__linux__)
00163 #ifndef NR_OPEN
00164 #define NR_OPEN (1024*1024)
00165 #endif
00166
00167
00168
00169
00170
00171 if (resource == isc_resource_openfiles && rlim_value == RLIM_INFINITY) {
00172 rl.rlim_cur = rl.rlim_max = NR_OPEN;
00173 unixresult = setrlimit(unixresource, &rl);
00174 if (unixresult == 0)
00175 return (ISC_R_SUCCESS);
00176 }
00177 #elif defined(__hpux) && defined(HAVE_SYS_DYNTUNE_H)
00178 if (resource == isc_resource_openfiles && rlim_value == RLIM_INFINITY) {
00179 uint64_t maxfiles;
00180 if (gettune("maxfiles_lim", &maxfiles) == 0) {
00181 rl.rlim_cur = rl.rlim_max = maxfiles;
00182 unixresult = setrlimit(unixresource, &rl);
00183 if (unixresult == 0)
00184 return (ISC_R_SUCCESS);
00185 }
00186 }
00187 #endif
00188 if (resource == isc_resource_openfiles && rlim_value == RLIM_INFINITY) {
00189 if (getrlimit(unixresource, &rl) == 0) {
00190 rl.rlim_cur = rl.rlim_max;
00191 unixresult = setrlimit(unixresource, &rl);
00192 if (unixresult == 0)
00193 return (ISC_R_SUCCESS);
00194 }
00195 }
00196 return (isc__errno2result(errno));
00197 }
00198
00199 isc_result_t
00200 isc_resource_getlimit(isc_resource_t resource, isc_resourcevalue_t *value) {
00201 int unixresult;
00202 int unixresource;
00203 struct rlimit rl;
00204 isc_result_t result;
00205
00206 result = resource2rlim(resource, &unixresource);
00207 if (result == ISC_R_SUCCESS) {
00208 unixresult = getrlimit(unixresource, &rl);
00209 INSIST(unixresult == 0);
00210 *value = rl.rlim_max;
00211 }
00212
00213 return (result);
00214 }
00215
00216 isc_result_t
00217 isc_resource_getcurlimit(isc_resource_t resource, isc_resourcevalue_t *value) {
00218 int unixresult;
00219 int unixresource;
00220 struct rlimit rl;
00221 isc_result_t result;
00222
00223 result = resource2rlim(resource, &unixresource);
00224 if (result == ISC_R_SUCCESS) {
00225 unixresult = getrlimit(unixresource, &rl);
00226 INSIST(unixresult == 0);
00227 *value = rl.rlim_cur;
00228 }
00229
00230 return (result);
00231 }