void do_prepare (int argc, char *argv[]) { size_t name_len; struct rlimit64 rlim; name_len = strlen (test_dir); name = malloc (name_len + sizeof ("/lfsXXXXXX")); mempcpy (mempcpy (name, test_dir, name_len), "/lfsXXXXXX", sizeof ("/lfsXXXXXX")); add_temp_file (name); /* Open our test file. */ fd = mkstemp64 (name); if (fd == -1) { if (errno == ENOSYS) { /* Fail silently. */ error (0, 0, "open64 is not supported"); exit (EXIT_SUCCESS); } else error (EXIT_FAILURE, errno, "cannot create temporary file"); } if (getrlimit64 (RLIMIT_FSIZE, &rlim) != 0) { error (0, errno, "cannot get resource limit"); exit (0); } if (rlim.rlim_cur < TWO_GB + 200) { rlim.rlim_cur = TWO_GB + 200; if (setrlimit64 (RLIMIT_FSIZE, &rlim) != 0) { error (0, errno, "cannot reset file size limits"); exit (0); } } }
qp_int_t qp_limit_opt(qp_int_t opt, qp_int_t source, qp_limit_t* limit) { if (!limit) { return QP_ERROR; } if (opt == QP_LIMIT_GET) { #ifdef __USE_LARGEFILE64 return getrlimit64(source, limit); #else return getrlimit(source, limit); #endif } #ifdef __USE_LARGEFILE64 return setrlimit64(source, limit); #else return setrlimit(source, limit); #endif }
/** * @brief * Establish system-enforced limits for the job. * * Run through the resource list, checking the values for all items * we recognize. * * @param[in] pjob - job pointer * @param[in] set_mode - setting mode * * If set_mode is SET_LIMIT_SET, then also set hard limits for the * system enforced limits (not-polled). * If anything goes wrong with the process, return a PBS error code * and print a message on standard error. A zero-length resource list * is not an error. * * If set_mode is SET_LIMIT_SET the entry conditions are: * 1. MOM has already forked, and we are called from the child. * 2. The child is still running as root. * 3. Standard error is open to the user's file. * * If set_mode is SET_LIMIT_ALTER, we are beening called to modify * existing limits. Cannot alter those set by setrlimit (kernel) * because we are the wrong process. * * @return int * @retval PBSE_NONE Success * @retval PBSE_* Error * */ int mom_set_limits(job *pjob, int set_mode) { char *pname; int retval; rlim64_t sizeval; /* place to build 64 bit value */ unsigned long value; /* place in which to build resource value */ resource *pres; struct rlimit64 res64lim; rlim64_t mem_limit = 0; rlim64_t vmem_limit = 0; rlim64_t cpu_limit = 0; #if NODEMASK != 0 __uint64_t rvalue; __uint64_t nodemask; #endif /* NODEMASK */ DBPRT(("%s: entered\n", __func__)) assert(pjob != NULL); assert(pjob->ji_wattr[(int)JOB_ATR_resource].at_type == ATR_TYPE_RESC); pres = (resource *) GET_NEXT(pjob->ji_wattr[(int)JOB_ATR_resource].at_val.at_list); /* * Cycle through all the resource specifications, * setting limits appropriately. */ /* mem and vmem limits come from the local node limits, not the job */ mem_limit = pjob->ji_hosts[pjob->ji_nodeid].hn_nrlimit.rl_mem << 10; vmem_limit = pjob->ji_hosts[pjob->ji_nodeid].hn_nrlimit.rl_vmem << 10; while (pres != NULL) { assert(pres->rs_defin != NULL); pname = pres->rs_defin->rs_name; assert(pname != NULL); assert(*pname != '\0'); if (strcmp(pname, "cput") == 0 || strcmp(pname, "pcput") == 0) { /* set */ retval = local_gettime(pres, &value); if (retval != PBSE_NONE) return (error(pname, retval)); if ((cpu_limit == 0) || (value < cpu_limit)) cpu_limit = value; } else if (strcmp(pname, "vmem") == 0 || strcmp(pname, "pvmem") == 0) { /* set */ retval = local_getsize(pres, &value); if (retval != PBSE_NONE) return (error(pname, retval)); if ((vmem_limit == 0) || (value < vmem_limit)) vmem_limit = value; } else if (strcmp(pname, "mem") == 0 || strcmp(pname, "pmem") == 0) { /* set */ retval = local_getsize(pres, &value); if (retval != PBSE_NONE) return (error(pname, retval)); if ((mem_limit == 0) || (value < mem_limit)) mem_limit = value; } else if (strcmp(pname, "file") == 0) { /* set */ if (set_mode == SET_LIMIT_SET) { retval = local_getsize(pres, &sizeval); if (retval != PBSE_NONE) return (error(pname, retval)); res64lim.rlim_cur = res64lim.rlim_max = sizeval; if (setrlimit64(RLIMIT_FSIZE, &res64lim) < 0) return (error(pname, PBSE_SYSTEM)); } } else if (strcmp(pname, "walltime") == 0) { /* Check */ retval = getlong(pres, &value); if (retval != PBSE_NONE) return (error(pname, retval)); } else if (strcmp(pname, "nice") == 0) { /* set nice */ if (set_mode == SET_LIMIT_SET) { errno = 0; if ((nice((int)pres->rs_value.at_val.at_long) == -1) && (errno != 0)) return (error(pname, PBSE_BADATVAL)); } #if NODEMASK != 0 } else if (strcmp(pname, "nodemask") == 0) { /* set nodemask */ /* call special node mask function */ nodemask = pres->rs_value.at_val.at_ll; rvalue = (__uint64_t)pmoctl(61, nodemask, 0); if (rvalue != nodemask) { (void)sprintf(log_buffer, "Tried to set node mask to 0x%0llx, was set to 0x%0llx", nodemask, rvalue); log_event(PBSEVENT_ERROR, PBS_EVENTCLASS_JOB, LOG_NOTICE, pjob->ji_qs.ji_jobid, log_buffer); } #endif /* NODEMASK */ } pres = (resource *)GET_NEXT(pres->rs_link); } if (set_mode == SET_LIMIT_SET) { /* if either mem or pmem was given, set sys limit to lesser */ if (mem_limit != 0) { res64lim.rlim_cur = res64lim.rlim_max = mem_limit; if (setrlimit64(RLIMIT_RSS, &res64lim) < 0) return (error("RLIMIT_RSS", PBSE_SYSTEM)); } /* if either cput or pcput was given, set sys limit to lesser */ if (cpu_limit != 0) { res64lim.rlim_cur = res64lim.rlim_max = (rlim64_t)((double)cpu_limit / cputfactor); if (setrlimit64(RLIMIT_CPU, &res64lim) < 0) return (error("RLIMIT_CPU", PBSE_SYSTEM)); } /* if either of vmem or pvmem was given, set sys limit to lesser */ if (vmem_limit != 0) { res64lim.rlim_cur = res64lim.rlim_max= vmem_limit; if (setrlimit64(RLIMIT_VMEM, &res64lim) < 0) return (error("RLIMIT_VMEM", PBSE_SYSTEM)); } } return (PBSE_NONE); }
int main(int argc, char **argv) { struct rlimit64 oldrlim; struct rlimit64 newrlim; int fd; CLOSE_INHERITED_FDS; if (getrlimit64(RLIMIT_NOFILE, &oldrlim) < 0) { perror("getrlimit"); exit(1); } newrlim.rlim_cur = oldrlim.rlim_max+1; newrlim.rlim_max = oldrlim.rlim_max; if (setrlimit64(RLIMIT_NOFILE, &newrlim) == -1) { if (errno != EINVAL) { fprintf(stderr, "setrlimit64 exceeding hardlimit must set errno=EINVAL\n"); exit(1); } } else { fprintf(stderr, "setrlimit64 exceeding hardlimit must return -1\n"); exit(1); } newrlim.rlim_cur = oldrlim.rlim_max; newrlim.rlim_max = oldrlim.rlim_max+1; if (setrlimit64(RLIMIT_NOFILE, &newrlim) == -1) { if (errno != EPERM) { fprintf(stderr, "setrlimit64 changing hardlimit must set errno=EPERM\n"); exit(1); } } else { fprintf(stderr, "setrlimit64 changing hardlimit must return -1\n"); exit(1); } newrlim.rlim_cur = oldrlim.rlim_cur / 2; newrlim.rlim_max = oldrlim.rlim_max; if (setrlimit64(RLIMIT_NOFILE, &newrlim) < 0) { perror("setrlimit64"); exit(1); } if (getrlimit64(RLIMIT_NOFILE, &newrlim) < 0) { perror("getrlimit"); exit(1); } if (newrlim.rlim_cur != oldrlim.rlim_cur / 2) { fprintf(stderr, "rlim_cur is %llu (should be %llu)\n", (unsigned long long)newrlim.rlim_cur, (unsigned long long)oldrlim.rlim_cur / 2); } if (newrlim.rlim_max != oldrlim.rlim_max) { fprintf(stderr, "rlim_max is %llu (should be %llu)\n", (unsigned long long)newrlim.rlim_max, (unsigned long long)oldrlim.rlim_max); } newrlim.rlim_cur -= 3; /* allow for stdin, stdout and stderr */ while (newrlim.rlim_cur-- > 0) { if (open("/dev/null", O_RDONLY) < 0) { perror("open"); } } if ((fd = open("/dev/null", O_RDONLY)) >= 0) { fprintf(stderr, "open succeeded with fd %d - it should have failed!\n", fd); } else if (errno != EMFILE) { perror("open"); } exit(0); }
TEST_F(SysResourceTest, setrlimit64) { l64_.rlim_cur = 456U; ASSERT_EQ(0, setrlimit64(RLIMIT_CORE, &l64_)); CheckResourceLimits(); ASSERT_EQ(456U, l64_.rlim_cur); }
/****** qmaster/sge_qmaster_main/set_file_descriptor_limit() ******************** * NAME * set_file_descriptor_limit() -- check and set file descriptor limit * * SYNOPSIS * static int set_file_descriptor_limit(void) * * FUNCTION * This function will check the file descriptor limit for the qmaster. If * soft limit < hard limit the soft limit will set to the hard limit, but * max. to 8192 file descriptors, even when the hard limit is higher. * * RESULT * 0 - success * 1 - can't set limit because FD_SETSIZE is to small * * * NOTES * MT-NOTE: set_file_descriptor_limit() is not MT safe because the limit * is a process specific parameter. This function should only be * called before starting up the threads. * *******************************************************************************/ static int set_file_descriptor_limit(void) { /* define the max qmaster file descriptor limit */ #define SGE_MAX_QMASTER_SOFT_FD_LIMIT 8192 int modified_hard_limit = 0; int return_value = 0; #if defined(IRIX) struct rlimit64 qmaster_rlimits; #else struct rlimit qmaster_rlimits; #endif /* * check file descriptor limits for qmaster */ #if defined(IRIX) getrlimit64(RLIMIT_NOFILE, &qmaster_rlimits); #else getrlimit(RLIMIT_NOFILE, &qmaster_rlimits); #endif /* check hard limit and set it to SGE_MAX_QMASTER_SOFT_FD_LIMIT if hard limit is smaller AND smaller than FD_SETSIZE */ if (qmaster_rlimits.rlim_max < SGE_MAX_QMASTER_SOFT_FD_LIMIT) { qmaster_rlimits.rlim_max = SGE_MAX_QMASTER_SOFT_FD_LIMIT; if (qmaster_rlimits.rlim_cur > SGE_MAX_QMASTER_SOFT_FD_LIMIT) { qmaster_rlimits.rlim_cur = SGE_MAX_QMASTER_SOFT_FD_LIMIT; } modified_hard_limit = 1; } #ifndef USE_POLL if (qmaster_rlimits.rlim_max > FD_SETSIZE) { qmaster_rlimits.rlim_max = FD_SETSIZE; if (qmaster_rlimits.rlim_cur > FD_SETSIZE) { qmaster_rlimits.rlim_cur = FD_SETSIZE; } modified_hard_limit = 1; return_value = 1; } #endif if (modified_hard_limit == 1) { #if defined(IRIX) setrlimit64(RLIMIT_NOFILE, &qmaster_rlimits); #else setrlimit(RLIMIT_NOFILE, &qmaster_rlimits); #endif } #if defined(IRIX) getrlimit64(RLIMIT_NOFILE, &qmaster_rlimits); #else getrlimit(RLIMIT_NOFILE, &qmaster_rlimits); #endif if (modified_hard_limit == 1) { /* if we have modified the hard limit by ourselfs we set SGE_MAX_QMASTER_SOFT_FD_LIMIT as soft limit (if possible) */ if ( qmaster_rlimits.rlim_cur < SGE_MAX_QMASTER_SOFT_FD_LIMIT && qmaster_rlimits.rlim_max < SGE_MAX_QMASTER_SOFT_FD_LIMIT ) { qmaster_rlimits.rlim_cur = qmaster_rlimits.rlim_max; } else { qmaster_rlimits.rlim_cur = SGE_MAX_QMASTER_SOFT_FD_LIMIT; } #if defined(IRIX) setrlimit64(RLIMIT_NOFILE, &qmaster_rlimits); #else setrlimit(RLIMIT_NOFILE, &qmaster_rlimits); #endif } else { /* if limits are set high enough through user we use the hard limit setting for the soft limit */ qmaster_rlimits.rlim_cur = qmaster_rlimits.rlim_max; #if defined(IRIX) setrlimit64(RLIMIT_NOFILE, &qmaster_rlimits); #else setrlimit(RLIMIT_NOFILE, &qmaster_rlimits); #endif } return return_value; }
/** * @brief * set limits for the pbs_comm process * * @return - Success/failure * @retval 0 - Success * @retval -1 - Failure * */ static void set_limits() { #ifdef RLIMIT_CORE int char_in_cname = 0; if (pbs_conf.pbs_core_limit) { char *pc = pbs_conf.pbs_core_limit; while (*pc != '\0') { if (!isdigit(*pc)) { /* there is a character in core limit */ char_in_cname = 1; break; } pc++; } } #endif /* RLIMIT_CORE */ #if defined(RLIM64_INFINITY) #ifndef WIN32 { struct rlimit64 rlimit; rlimit.rlim_cur = TPP_MAXOPENFD; rlimit.rlim_max = TPP_MAXOPENFD; if (setrlimit64(RLIMIT_NOFILE, &rlimit) == -1) { log_err(errno, __func__, "could not set max open files limit"); } rlimit.rlim_cur = RLIM64_INFINITY; rlimit.rlim_max = RLIM64_INFINITY; (void)setrlimit64(RLIMIT_CPU, &rlimit); (void)setrlimit64(RLIMIT_FSIZE, &rlimit); (void)setrlimit64(RLIMIT_DATA, &rlimit); (void)setrlimit64(RLIMIT_STACK, &rlimit); #ifdef RLIMIT_RSS (void)setrlimit64(RLIMIT_RSS , &rlimit); #endif /* RLIMIT_RSS */ #ifdef RLIMIT_VMEM (void)setrlimit64(RLIMIT_VMEM , &rlimit); #endif /* RLIMIT_VMEM */ #ifdef RLIMIT_CORE if (pbs_conf.pbs_core_limit) { struct rlimit64 corelimit; corelimit.rlim_max = RLIM64_INFINITY; if (strcmp("unlimited", pbs_conf.pbs_core_limit) == 0) corelimit.rlim_cur = RLIM64_INFINITY; else if (char_in_cname == 1) { log_record(PBSEVENT_ERROR, PBS_EVENTCLASS_SERVER, LOG_WARNING, __func__, msg_corelimit); corelimit.rlim_cur = RLIM64_INFINITY; } else corelimit.rlim_cur = (rlim64_t)atol(pbs_conf.pbs_core_limit); (void)setrlimit64(RLIMIT_CORE, &corelimit); } #endif /* RLIMIT_CORE */ } #endif /* WIN32 */ #else /* setrlimit 32 bit */ #ifndef WIN32 { struct rlimit rlimit; rlimit.rlim_cur = TPP_MAXOPENFD; rlimit.rlim_max = TPP_MAXOPENFD; if (setrlimit(RLIMIT_NOFILE, &rlimit) == -1) { log_err(errno, __func__, "could not set max open files limit"); } rlimit.rlim_cur = RLIM_INFINITY; rlimit.rlim_max = RLIM_INFINITY; (void)setrlimit(RLIMIT_CPU, &rlimit); #ifdef RLIMIT_RSS (void)setrlimit(RLIMIT_RSS, &rlimit); #endif /* RLIMIT_RSS */ #ifdef RLIMIT_VMEM (void)setrlimit(RLIMIT_VMEM, &rlimit); #endif /* RLIMIT_VMEM */ #ifdef RLIMIT_CORE if (pbs_conf.pbs_core_limit) { struct rlimit corelimit; corelimit.rlim_max = RLIM_INFINITY; if (strcmp("unlimited", pbs_conf.pbs_core_limit) == 0) corelimit.rlim_cur = RLIM_INFINITY; else if (char_in_cname == 1) { log_record(PBSEVENT_ERROR, PBS_EVENTCLASS_SERVER, LOG_WARNING, (char *) __func__, msg_corelimit); corelimit.rlim_cur = RLIM_INFINITY; } else #ifdef _SX corelimit.rlim_cur = atol(pbs_conf.pbs_core_limit); #else corelimit.rlim_cur = (rlim_t)atol(pbs_conf.pbs_core_limit); #endif /* _SX */ (void)setrlimit(RLIMIT_CORE, &corelimit); } #endif /* RLIMIT_CORE */ #ifndef linux (void)setrlimit(RLIMIT_FSIZE, &rlimit); (void)setrlimit(RLIMIT_DATA, &rlimit); (void)setrlimit(RLIMIT_STACK, &rlimit); #else if (getrlimit(RLIMIT_STACK, &rlimit) != -1) { if((rlimit.rlim_cur != RLIM_INFINITY) && (rlimit.rlim_cur < MIN_STACK_LIMIT)) { rlimit.rlim_cur = MIN_STACK_LIMIT; rlimit.rlim_max = MIN_STACK_LIMIT; if (setrlimit(RLIMIT_STACK, &rlimit) == -1) { log_err(errno, __func__, "setting stack limit failed"); exit(1); } } } else { log_err(errno, __func__, "getting current stack limit failed"); exit(1); } #endif /* not linux */ } #endif /* WIN32 */ #endif /* !RLIM64_INFINITY */ }