diff --git a/maestro/core.c b/maestro/core.c index 8837e2aee3f52432201207879553e54466a62fae..ddc539c2de5f8abffd506aaebaf6317a54e847fd 100644 --- a/maestro/core.c +++ b/maestro/core.c @@ -49,6 +49,7 @@ #include <inttypes.h> #include <string.h> #include <assert.h> +#include <sys/resource.h> #include "maestro/i_state.h" #include "transport/transport.h" @@ -295,6 +296,66 @@ mstro_status mstro_core_init__setup_schemata(void) return status; } +/** the number of RLIMIT_ values in the table of @ref MSTRO_DEFAULT_RLIMIT definitions */ +#define MSTRO_DEFAULT_RLIMIT_LEN 2 + +/** the list of minimal RLIMIT_ values maestro-core needs to be happy */ +struct { + const char* name; /**< name of resource */ + int resource; /**< the RLIMIT_ constant to designate the resource */ + rlim_t desired_val; /**< the value we believe maestro-core needs at least */ +} MSTRO_DEFAULT_RLIMIT[MSTRO_DEFAULT_RLIMIT_LEN] = { + {"RLIMIT_NOFILE", RLIMIT_NOFILE, 1024}, + {"RLIMIT_MEMLOCK", RLIMIT_MEMLOCK, MSTRO_MIN_MEMLOCK}, +}; + +static inline +void +mstro_core__adapt_rlimits(void) +{ + // check some typical limits and try to increase (or warn) + + for(size_t i=0; i<MSTRO_DEFAULT_RLIMIT_LEN; i++) { + struct rlimit rlp; + + int s = getrlimit(MSTRO_DEFAULT_RLIMIT[i].resource, &rlp); + if(s!=0) { + ERR("Failed to query %s value: %d (%s)\n", + MSTRO_DEFAULT_RLIMIT[i].name, s, strerror(s)); + } else { + DEBUG("%s: soft %zu, hard %zu\n", + MSTRO_DEFAULT_RLIMIT[i].name, + (uintmax_t)rlp.rlim_cur, + (uintmax_t)rlp.rlim_max); + if(rlp.rlim_cur<MSTRO_DEFAULT_RLIMIT[i].desired_val) { + WARN("%s: soft limit %zu is lower than desired value %zu, trying to increase it.\n", + MSTRO_DEFAULT_RLIMIT[i].name, + (uintmax_t)rlp.rlim_cur, + (uintmax_t)MSTRO_DEFAULT_RLIMIT[i].desired_val); + if(rlp.rlim_max<MSTRO_DEFAULT_RLIMIT[i].desired_val) { + WARN("%s: hard limit %zu is lower than desired value %zu, cannot increase it. Proceeding with fingers crossed.\n", + MSTRO_DEFAULT_RLIMIT[i].name, + (uintmax_t)rlp.rlim_max, + (uintmax_t)MSTRO_DEFAULT_RLIMIT[i].desired_val); + } else { + rlp.rlim_cur = MSTRO_DEFAULT_RLIMIT[i].desired_val; + s=setrlimit(MSTRO_DEFAULT_RLIMIT[i].resource, &rlp); + if(s!=0) { + ERR("Failed to raise soft limit of %s to %zu: %d (%s)\n", + MSTRO_DEFAULT_RLIMIT[i].name, + (uintmax_t)rlp.rlim_cur, + s, strerror(s)); + } else { + DEBUG("%s raised to %zu\n", + MSTRO_DEFAULT_RLIMIT[i].name, (uintmax_t)rlp.rlim_cur); + } + } + } + } + } +} + + mstro_status mstro_core_init(const char *workflow_name, const char *component_name, @@ -302,11 +363,14 @@ mstro_core_init(const char *workflow_name, { mstro_status status = MSTRO_UNIMPL; + mstro_core__adapt_rlimits(); + status = mstro_memlock_init(MSTRO_MIN_MEMLOCK); if(status!=MSTRO_OK) { return status; } + struct mstro_core_initdata *data = malloc(sizeof(struct mstro_core_initdata)); if(data) {