From d09a9e8096d8d4eb69e0dc6eed7deb1151aea69c Mon Sep 17 00:00:00 2001 From: Ralph Castain Date: Wed, 3 Apr 2013 18:57:53 +0000 Subject: [PATCH] Upgrade the system limit code to support a broader range of parameters. For now, we support stack size, #open files, #children, and file size we can c reate. Continue to support the old "1" or "0" options for backward compatibility. This commit was SVN r28282. --- opal/runtime/opal_params.c | 11 ++-- opal/runtime/opal_params.h | 4 +- opal/util/sys_limits.c | 120 +++++++++++++++++++++++++++---------- 3 files changed, 96 insertions(+), 39 deletions(-) diff --git a/opal/runtime/opal_params.c b/opal/runtime/opal_params.c index 8a34e7dd7b..df4e4c6a66 100644 --- a/opal/runtime/opal_params.c +++ b/opal/runtime/opal_params.c @@ -13,7 +13,7 @@ * reserved. * Copyright (c) 2008-2012 Cisco Systems, Inc. All rights reserved. * Copyright (c) 2009 Oak Ridge National Labs. All rights reserved. - * Copyright (c) 2010 Los Alamos National Security, LLC. + * Copyright (c) 2010-2013 Los Alamos National Security, LLC. * All rights reserved. * $COPYRIGHT$ * @@ -42,7 +42,7 @@ char *opal_signal_string = NULL; char *opal_net_private_ipv4 = NULL; -bool opal_set_max_sys_limits = false; +char *opal_set_max_sys_limits = NULL; int opal_register_params(void) { @@ -152,10 +152,11 @@ int opal_register_params(void) return ret; } - opal_set_max_sys_limits = false; + opal_set_max_sys_limits = NULL; ret = mca_base_var_register ("opal", "opal", NULL, "set_max_sys_limits", - "Set to non-zero to automatically set any system-imposed limits to the maximum allowed", - MCA_BASE_VAR_TYPE_BOOL, NULL, 0, MCA_BASE_VAR_FLAG_SETTABLE, + "Set the specified system-imposed limits to the specified value, including \"unlimited\"." + "Supported params: core, filesize, maxmem, openfiles, stacksize, maxchildren", + MCA_BASE_VAR_TYPE_STRING, NULL, 0, MCA_BASE_VAR_FLAG_SETTABLE, OPAL_INFO_LVL_3, MCA_BASE_VAR_SCOPE_ALL_EQ, &opal_set_max_sys_limits); if (0 > ret) { diff --git a/opal/runtime/opal_params.h b/opal/runtime/opal_params.h index c0628b2738..7a0f23c3fe 100644 --- a/opal/runtime/opal_params.h +++ b/opal/runtime/opal_params.h @@ -13,7 +13,7 @@ * reserved. * Copyright (c) 2008-2012 Cisco Systems, Inc. All rights reserved. * Copyright (c) 2009 Oak Ridge National Labs. All rights reserved. - * Copyright (c) 2010 Los Alamos National Security, LLC. + * Copyright (c) 2010-2013 Los Alamos National Security, LLC. * All rights reserved. * $COPYRIGHT$ * @@ -27,7 +27,7 @@ extern char *opal_signal_string; extern char *opal_net_private_ipv4; -extern bool opal_set_max_sys_limits; +extern char *opal_set_max_sys_limits; #if OPAL_ENABLE_DEBUG extern bool opal_progress_debug; diff --git a/opal/util/sys_limits.c b/opal/util/sys_limits.c index 22843baee4..5f04a9201f 100644 --- a/opal/util/sys_limits.c +++ b/opal/util/sys_limits.c @@ -10,6 +10,8 @@ * Copyright (c) 2004-2005 The Regents of the University of California. * All rights reserved. * Copyright (c) 2007 Cisco Systems, Inc. All rights reserved. + * Copyright (c) 2013 Los Alamos National Security, LLC. + * All rights reserved. * $COPYRIGHT$ * * Additional copyrights may follow @@ -42,7 +44,7 @@ #include "opal/util/sys_limits.h" #include "opal/util/output.h" - +#include "opal/util/argv.h" /* * Create and initialize storage for the system limits @@ -54,50 +56,104 @@ OPAL_DECLSPEC opal_sys_limits_t opal_sys_limits = { /* file_size = */ 0 }; -int opal_util_init_sys_limits(void) +static rlim_t opal_setlimit(int resource, char *value) { struct rlimit rlim, rlim_set; + rlim_t maxlim; + + rlim.rlim_cur = 0; + + if (0 == strcmp(value, "max")) { + maxlim = -1; + } else if (0 == strncmp(value, "unlimited", strlen(value))) { + maxlim = RLIM_INFINITY; + } else { + maxlim = strtol(value, NULL, 10); + } - /* get/set the system limits on number of files we can have open */ if (0 <= getrlimit (RLIMIT_NOFILE, &rlim)) { - if (opal_set_max_sys_limits) { - rlim_set.rlim_cur = rlim.rlim_max; + if (maxlim < 0) { + rlim_set.rlim_cur = rlim.rlim_cur; rlim_set.rlim_max = rlim.rlim_max; - if (0 <= setrlimit (RLIMIT_NOFILE, &rlim_set)) { - rlim.rlim_cur = rlim.rlim_max; - } + } else { + rlim_set.rlim_cur = maxlim; + rlim_set.rlim_max = maxlim; } - opal_sys_limits.num_files = rlim.rlim_cur; + if (0 <= setrlimit (RLIMIT_NOFILE, &rlim_set)) { + rlim.rlim_cur = rlim.rlim_cur; + } + } + return rlim.rlim_cur; +} + +int opal_util_init_sys_limits(void) +{ + char **lims, **lim, *setlim; + int i; + + /* if limits were not given, then nothing to do */ + if (NULL == opal_set_max_sys_limits) { + return OPAL_SUCCESS; } + /* parse the requested limits to set */ + lims = opal_argv_split(opal_set_max_sys_limits, ','); + + /* each limit is expressed as a "param:value" pair */ + for (i=0; NULL != lims[i]; i++) { + lim = opal_argv_split(lims[i], ':'); + if (1 == opal_argv_count(lim)) { + setlim = "max"; + } else { + setlim = lim[1]; + } + + /* for historical reasons, a value of "1" means + * that we set the limits on #files, #children, + * and max file size + */ + if (0 == strcmp(lim[0], "1")) { + opal_sys_limits.num_files = opal_setlimit(RLIMIT_NOFILE, "max"); #if HAVE_DECL_RLIMIT_NPROC - /* get/set the system limits on number of child procs we can have open */ - if (0 <= getrlimit (RLIMIT_NPROC, &rlim)) { - if (opal_set_max_sys_limits) { - rlim_set.rlim_cur = rlim.rlim_max; - rlim_set.rlim_max = rlim.rlim_max; - if (0 <= setrlimit (RLIMIT_NPROC, &rlim_set)) { - rlim.rlim_cur = rlim.rlim_max; - } - } - opal_sys_limits.num_procs = rlim.rlim_cur; - } + opal_sys_limits.num_procs = opal_setlimit(RLIMIT_NPROC, "max"); #endif - - /* get/set the system limits on max file size we can create */ - if (0 <= getrlimit (RLIMIT_FSIZE, &rlim)) { - if (opal_set_max_sys_limits) { - rlim_set.rlim_cur = rlim.rlim_max; - rlim_set.rlim_max = rlim.rlim_max; - if (0 <= setrlimit (RLIMIT_FSIZE, &rlim_set)) { - rlim.rlim_cur = rlim.rlim_max; - } + opal_sys_limits.file_size = opal_setlimit(RLIMIT_FSIZE, "max"); + break; + } else if (0 == strcmp(lim[0], "0")) { + /* user didn't want anything set */ + goto cleanup; + } + + /* process them separately */ + if (0 == strcmp(lim[0], "core")) { + opal_setlimit(RLIMIT_CORE, setlim); + } else if (0 == strcmp(lim[0], "filesize")) { + opal_setlimit(RLIMIT_FSIZE, setlim); + } else if (0 == strcmp(lim[0], "maxmem")) { + opal_setlimit(RLIMIT_AS, setlim); + } else if (0 == strcmp(lim[0], "openfiles")) { + opal_setlimit(RLIMIT_NOFILE, setlim); + } else if (0 == strcmp(lim[0], "stacksize")) { + opal_setlimit(RLIMIT_STACK, setlim); +#if HAVE_DECL_RLIMIT_NPROC + } else if (0 == strcmp(lim[0], "maxchildren")) { + opal_setlimit(RLIMIT_NPROC, "max"); +#endif + } else { + opal_output(0, "Unrecognized setlimit option: %s - ignored", lim[0]); } - opal_sys_limits.file_size = rlim.rlim_cur; } - + + cleanup: + if (NULL != lim) { + opal_argv_free(lim); + } + if (NULL != lims) { + opal_argv_free(lims); + } + /* indicate we initialized the limits structure */ opal_sys_limits.initialized = true; - return OPAL_SUCCESS; + return OPAL_SUCCESS; }