/*****************************************************************************\ * slurm_rlimits_info.c - resource limits that are used by srun and the slurmd ***************************************************************************** * Copyright (C) 2005 Hewlett-Packard Development Company, L.P. * * This file is part of Slurm, a resource management program. * For details, see . * Please also read the included file: DISCLAIMER. * * Slurm is free software; you can redistribute it and/or modify it under * the terms of the GNU General Public License as published by the Free * Software Foundation; either version 2 of the License, or (at your option) * any later version. * * In addition, as a special exception, the copyright holders give permission * to link the code of portions of this program with the OpenSSL library under * certain conditions as described in each individual source file, and * distribute linked combinations including the two. You must obey the GNU * General Public License in all respects for all of the code used other than * OpenSSL. If you modify file(s) with this exception, you may extend this * exception to your version of the file(s), but you are not obligated to do * so. If you do not wish to do so, delete this exception statement from your * version. If you delete this exception statement from all source files in * the program, then also delete it here. * * Slurm is distributed in the hope that it will be useful, but WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * details. * * You should have received a copy of the GNU General Public License along * with Slurm; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. \*****************************************************************************/ #include #include #include /* for OPEN_MAX on macOS */ #include #include #include "src/common/macros.h" #include "src/common/xstring.h" #include "src/common/xassert.h" #include "src/common/xmalloc.h" #include "src/common/log.h" #include "src/common/slurm_rlimits_info.h" /* * List Slurm rlimits get/setrlimit resource number with associated name and * whether it should be propagated. */ static slurm_rlimits_info_t rlimits_info[] = { /* resource, name, propagate_flag */ #ifdef RLIMIT_CPU { RLIMIT_CPU, "CPU", PROPAGATE_RLIMITS_NOT_SET }, #endif #ifdef RLIMIT_FSIZE { RLIMIT_FSIZE, "FSIZE", PROPAGATE_RLIMITS_NOT_SET }, #endif #ifdef RLIMIT_DATA { RLIMIT_DATA, "DATA", PROPAGATE_RLIMITS_NOT_SET }, #endif #ifdef RLIMIT_STACK { RLIMIT_STACK, "STACK", PROPAGATE_RLIMITS_NOT_SET }, #endif #ifdef RLIMIT_CORE { RLIMIT_CORE, "CORE", PROPAGATE_RLIMITS_NOT_SET }, #endif #ifdef RLIMIT_RSS { RLIMIT_RSS, "RSS", PROPAGATE_RLIMITS_NOT_SET }, #endif #ifdef RLIMIT_NPROC { RLIMIT_NPROC, "NPROC", PROPAGATE_RLIMITS_NOT_SET }, #endif #ifdef RLIMIT_NOFILE { RLIMIT_NOFILE, "NOFILE", PROPAGATE_RLIMITS_NOT_SET }, #endif #ifdef RLIMIT_MEMLOCK { RLIMIT_MEMLOCK, "MEMLOCK", PROPAGATE_RLIMITS_NOT_SET }, #endif #ifdef RLIMIT_AS { RLIMIT_AS, "AS", PROPAGATE_RLIMITS_NOT_SET }, #endif { 0, NULL, PROPAGATE_RLIMITS_NOT_SET } }; static bool rlimits_were_parsed = false; /* * Return a pointer to the private rlimits info array. */ slurm_rlimits_info_t * get_slurm_rlimits_info( void ) { xassert( rlimits_were_parsed == true ); return rlimits_info; } #define RLIMIT_ "RLIMIT_" #define LEN_RLIMIT_ (sizeof( RLIMIT_ ) - 1) #define RLIMIT_DELIMS ", \t\n" /* * Parse a comma separated list of RLIMIT names. * * Return 0 on success, or -1 if the 'rlimits_str' input parameter contains * a name that is not in rlimits_info[]. */ int parse_rlimits( char *rlimits_str, int propagate_flag ) { slurm_rlimits_info_t *rli; /* ptr iterator for rlimits_info[] */ char *tp; /* token ptr */ bool found; bool propagate_none = false; char *rlimits_str_dup; xassert( rlimits_str ); if (xstrcmp(rlimits_str, "NONE") == 0) { propagate_none = true; propagate_flag = !propagate_flag; } if (propagate_none || xstrcmp( rlimits_str, "ALL" ) == 0) { /* * Propagate flag value applies to all rlimits */ for (rli = rlimits_info; rli->name; rli++) rli->propagate_flag = propagate_flag; rlimits_were_parsed = true; return( 0 ); } /* * Since parse_rlimits may be called multiple times, we * need to reinitialize the propagate flags when individual * rlimits are specified. */ if (rlimits_were_parsed) for (rli = rlimits_info; rli->name; rli++) rli->propagate_flag = PROPAGATE_RLIMITS_NOT_SET; rlimits_str_dup = xstrdup( rlimits_str ); tp = strtok( rlimits_str_dup, RLIMIT_DELIMS ); while (tp != NULL) { found = false; for (rli = rlimits_info; rli->name; rli++) { /* * Accept either "RLIMIT_CORE" or "CORE" */ if (xstrncmp( tp, RLIMIT_, LEN_RLIMIT_ ) == 0) tp += LEN_RLIMIT_; if (xstrcmp( tp, rli->name )) continue; rli->propagate_flag = propagate_flag; found = true; break; } if (found == false) { error( "Bad rlimit name: %s", tp ); xfree( rlimits_str_dup ); return( -1 ); } tp = strtok( NULL, RLIMIT_DELIMS ); } xfree( rlimits_str_dup ); /* * Any rlimits that weren't in the 'rlimits_str' parameter get the * opposite propagate flag value. */ for (rli = rlimits_info; rli->name; rli++) if (rli->propagate_flag == PROPAGATE_RLIMITS_NOT_SET) rli->propagate_flag = ( ! propagate_flag ); rlimits_were_parsed = true; return( 0 ); } extern void print_rlimits(void) { slurm_rlimits_info_t *rli; /* ptr iterator for rlimits_info[] */ struct rlimit rlp; for (rli = rlimits_info; rli->name; rli++) { if (getrlimit(rli->resource, &rlp) == 0) { printf("SLURM_RLIMIT_%s=%lu\n", rli->name, (unsigned long) rlp.rlim_cur); } } } extern void rlimits_maximize_nofile(void) { struct rlimit rlim; if (getrlimit(RLIMIT_NOFILE, &rlim) < 0) error("getrlimit(RLIMIT_NOFILE): %m"); if (rlim.rlim_cur < rlim.rlim_max) { #if defined(__APPLE__) rlim.rlim_cur = MIN(OPEN_MAX, rlim.rlim_max); #else rlim.rlim_cur = rlim.rlim_max; #endif if (setrlimit(RLIMIT_NOFILE, &rlim) < 0) error("Unable to increase maximum number of open files: %m"); } }